pinokiod 3.132.0 → 3.134.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.
- package/kernel/connect/backend.js +0 -1
- package/kernel/connect/providers/huggingface/index.js +0 -1
- package/kernel/index.js +1 -1
- package/kernel/router/localhost_static_router.js +21 -1
- package/kernel/router/peer_static_router.js +4 -0
- package/kernel/router/rewriter.js +15 -7
- package/package.json +1 -1
- package/server/index.js +20 -9
- package/server/public/nav.js +304 -7
- package/server/public/style.css +82 -0
- package/server/views/app.ejs +170 -0
- package/server/views/connect/x.ejs +3 -0
- package/server/views/connect.ejs +3 -0
- package/server/views/container.ejs +3 -0
- package/server/views/download.ejs +3 -0
- package/server/views/explore.ejs +3 -0
- package/server/views/form.ejs +3 -0
- package/server/views/frame.ejs +3 -0
- package/server/views/github.ejs +3 -0
- package/server/views/help.ejs +3 -0
- package/server/views/index.ejs +3 -0
- package/server/views/index2.ejs +3 -0
- package/server/views/init/index.ejs +3 -0
- package/server/views/mini.ejs +3 -0
- package/server/views/net.ejs +3 -0
- package/server/views/network.ejs +3 -0
- package/server/views/network2.ejs +3 -0
- package/server/views/old_network.ejs +3 -0
- package/server/views/prototype/index.ejs +3 -0
- package/server/views/review.ejs +3 -0
- package/server/views/screenshots.ejs +3 -0
- package/server/views/settings.ejs +3 -0
- package/server/views/setup.ejs +3 -0
- package/server/views/setup_home.ejs +3 -0
- package/server/views/terminals.ejs +3 -0
- package/server/views/tools.ejs +3 -0
|
@@ -47,7 +47,6 @@ class Backend {
|
|
|
47
47
|
let authPath = this.kernel.path(`connect/${this.name}/auth.json`)
|
|
48
48
|
this.auth = (await this.kernel.loader.load(authPath)).resolved
|
|
49
49
|
if (!this.auth) {
|
|
50
|
-
console.log("not authenticated")
|
|
51
50
|
return null
|
|
52
51
|
}
|
|
53
52
|
if (!this.auth.refresh_token) {
|
package/kernel/index.js
CHANGED
|
@@ -488,7 +488,7 @@ class Kernel {
|
|
|
488
488
|
let changed
|
|
489
489
|
let new_config = JSON.stringify(await this.peer.current_host())
|
|
490
490
|
if (this.old_config !== new_config) {
|
|
491
|
-
console.log("Proc config has changed. update router.")
|
|
491
|
+
// console.log("Proc config has changed. update router.")
|
|
492
492
|
changed = true
|
|
493
493
|
} else {
|
|
494
494
|
// console.log("Proc config is the same")
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
const fs = require('fs')
|
|
1
2
|
const path = require('path')
|
|
2
3
|
const Common = require('./common')
|
|
3
4
|
const Rewriter = require('./rewriter')
|
|
@@ -23,6 +24,19 @@ class LocalhostStaticRouter extends Processor {
|
|
|
23
24
|
}
|
|
24
25
|
}
|
|
25
26
|
for(let { api_name, config } of configs) {
|
|
27
|
+
const apiRoot = this.router.kernel.path('api', api_name)
|
|
28
|
+
const indexPath = path.join(apiRoot, 'index.html')
|
|
29
|
+
const hasMenu = Boolean(config.menu)
|
|
30
|
+
if (hasMenu) {
|
|
31
|
+
delete this.router.rewrite_mapping[api_name]
|
|
32
|
+
continue
|
|
33
|
+
}
|
|
34
|
+
const hasIndex = fs.existsSync(indexPath)
|
|
35
|
+
const fileServerOptions = {}
|
|
36
|
+
if (hasIndex) {
|
|
37
|
+
fileServerOptions.index_names = ["index.html"]
|
|
38
|
+
}
|
|
39
|
+
const effectiveFileServerOptions = Object.keys(fileServerOptions).length ? { ...fileServerOptions } : undefined
|
|
26
40
|
for(let domain in config.dns) {
|
|
27
41
|
let localhost_match
|
|
28
42
|
let peer_match
|
|
@@ -45,11 +59,13 @@ class LocalhostStaticRouter extends Processor {
|
|
|
45
59
|
route: rewrite,
|
|
46
60
|
match: [localhost_match],
|
|
47
61
|
dial: local_dial,
|
|
62
|
+
fileServerOptions: effectiveFileServerOptions,
|
|
48
63
|
})
|
|
49
64
|
this.rewriter.handle({
|
|
50
65
|
route: rewrite,
|
|
51
66
|
match: [peer_match],
|
|
52
67
|
dial: peer_dial,
|
|
68
|
+
fileServerOptions: effectiveFileServerOptions,
|
|
53
69
|
})
|
|
54
70
|
|
|
55
71
|
// this.router.add_rewrite({ route: new_path, match, peer, dial })
|
|
@@ -64,7 +80,7 @@ class LocalhostStaticRouter extends Processor {
|
|
|
64
80
|
|
|
65
81
|
|
|
66
82
|
|
|
67
|
-
|
|
83
|
+
const rewriteEntry = {
|
|
68
84
|
name: api_name,
|
|
69
85
|
internal_router: [
|
|
70
86
|
`${local_dial}${rewrite}`,
|
|
@@ -75,6 +91,10 @@ class LocalhostStaticRouter extends Processor {
|
|
|
75
91
|
peer_match
|
|
76
92
|
]
|
|
77
93
|
}
|
|
94
|
+
if (effectiveFileServerOptions) {
|
|
95
|
+
rewriteEntry.file_server_options = effectiveFileServerOptions
|
|
96
|
+
}
|
|
97
|
+
this.router.rewrite_mapping[api_name] = rewriteEntry
|
|
78
98
|
// this.connector.handle({
|
|
79
99
|
// match: peer_match,
|
|
80
100
|
// connector: {
|
|
@@ -33,10 +33,14 @@ class PeerStaticRouter extends Processor {
|
|
|
33
33
|
let url = new URL("http://" + rewrite_mapping.external_ip)
|
|
34
34
|
let dial = url.host
|
|
35
35
|
let rewrite = url.pathname
|
|
36
|
+
const fileServerOptions = rewrite_mapping.file_server_options
|
|
37
|
+
? { ...rewrite_mapping.file_server_options }
|
|
38
|
+
: undefined
|
|
36
39
|
this.rewriter.handle({
|
|
37
40
|
route: url.pathname,
|
|
38
41
|
match: rewrite_mapping.external_router,
|
|
39
42
|
dial: url.host,
|
|
43
|
+
fileServerOptions,
|
|
40
44
|
})
|
|
41
45
|
}
|
|
42
46
|
}
|
|
@@ -4,7 +4,7 @@ class Rewriter extends Processor {
|
|
|
4
4
|
super()
|
|
5
5
|
this.router = router
|
|
6
6
|
}
|
|
7
|
-
handle({ match, dial, route }) {
|
|
7
|
+
handle({ match, dial, route, fileServerOptions }) {
|
|
8
8
|
//let rewrite = `${route}/{path}`
|
|
9
9
|
//let rewrite = `${route}{http.request.uri}`
|
|
10
10
|
/*
|
|
@@ -35,24 +35,32 @@ class Rewriter extends Processor {
|
|
|
35
35
|
|
|
36
36
|
// stript the leading /asset/ => (/asset/api/test => /api/test)
|
|
37
37
|
const asset_path = this.router.kernel.path(route.replace(/\/asset\//, ''))
|
|
38
|
-
|
|
38
|
+
|
|
39
|
+
const fileServerHandler = {
|
|
39
40
|
"handler": "file_server",
|
|
40
41
|
"root": asset_path,
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
42
|
+
...fileServerOptions
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const handlers = [fileServerHandler]
|
|
44
46
|
|
|
45
47
|
// if the dial port has been overridden by router.custom_routers, use that instead
|
|
46
48
|
let parsed_dial = this.parse_ip(dial)
|
|
47
49
|
let override_handler = this.router.custom_routers[String(parsed_dial.port)]
|
|
48
50
|
if (override_handler) {
|
|
49
|
-
|
|
51
|
+
this.router.config.apps.http.servers.main.routes.push({
|
|
52
|
+
"match": [{
|
|
53
|
+
"host": match ,
|
|
54
|
+
}],
|
|
55
|
+
"handle": override_handler
|
|
56
|
+
})
|
|
57
|
+
return
|
|
50
58
|
}
|
|
51
59
|
this.router.config.apps.http.servers.main.routes.push({
|
|
52
60
|
"match": [{
|
|
53
61
|
"host": match ,
|
|
54
62
|
}],
|
|
55
|
-
"handle":
|
|
63
|
+
"handle": handlers
|
|
56
64
|
})
|
|
57
65
|
}
|
|
58
66
|
}
|
package/package.json
CHANGED
package/server/index.js
CHANGED
|
@@ -460,9 +460,16 @@ class Server {
|
|
|
460
460
|
}
|
|
461
461
|
async renderIndex(name, cfg) {
|
|
462
462
|
let p = this.kernel.path("api", name)
|
|
463
|
-
let
|
|
464
|
-
let
|
|
465
|
-
|
|
463
|
+
let index_path = path.resolve(p, "index.html")
|
|
464
|
+
let index_exists = await this.kernel.exists(index_path)
|
|
465
|
+
let c = cfg
|
|
466
|
+
let menu = []
|
|
467
|
+
if (cfg.menu) {
|
|
468
|
+
({ menu, ...c } = cfg)
|
|
469
|
+
}
|
|
470
|
+
console.log("Menu", menu)
|
|
471
|
+
console.log("c", c)
|
|
472
|
+
if (index_exists) {
|
|
466
473
|
return Object.assign({
|
|
467
474
|
title: name,
|
|
468
475
|
menu: [{
|
|
@@ -470,8 +477,8 @@ class Server {
|
|
|
470
477
|
icon: "fa-solid fa-link",
|
|
471
478
|
text: "index.html",
|
|
472
479
|
href: `/asset/api/${name}/index.html`,
|
|
473
|
-
}]
|
|
474
|
-
},
|
|
480
|
+
}].concat(menu)
|
|
481
|
+
}, c)
|
|
475
482
|
} else {
|
|
476
483
|
return Object.assign({
|
|
477
484
|
title: name,
|
|
@@ -480,8 +487,8 @@ class Server {
|
|
|
480
487
|
icon: "fa-solid fa-link",
|
|
481
488
|
text: "Project Files",
|
|
482
489
|
href: `/files/api/${name}`,
|
|
483
|
-
}]
|
|
484
|
-
},
|
|
490
|
+
}].concat(menu)
|
|
491
|
+
}, c)
|
|
485
492
|
}
|
|
486
493
|
}
|
|
487
494
|
async getGit(ref, filepath) {
|
|
@@ -688,7 +695,7 @@ class Server {
|
|
|
688
695
|
if (config && config.version) {
|
|
689
696
|
let coerced = semver.coerce(config.version)
|
|
690
697
|
if (semver.satisfies(coerced, this.kernel.schema)) {
|
|
691
|
-
console.log("semver satisfied", config.version, this.kernel.schema)
|
|
698
|
+
// console.log("semver satisfied", config.version, this.kernel.schema)
|
|
692
699
|
} else {
|
|
693
700
|
console.log("semver NOT satisfied", config.version, this.kernel.schema)
|
|
694
701
|
err = `Please update to the latest Pinokio (current script version: ${config.version}, supported: ${this.kernel.schema})`
|
|
@@ -3712,7 +3719,11 @@ class Server {
|
|
|
3712
3719
|
this.app.use(express.json());
|
|
3713
3720
|
this.app.use(express.urlencoded({ extended: true }));
|
|
3714
3721
|
this.app.use(cookieParser());
|
|
3715
|
-
this.app.use(session({
|
|
3722
|
+
this.app.use(session({
|
|
3723
|
+
secret: "secret",
|
|
3724
|
+
resave: false,
|
|
3725
|
+
saveUninitialized: false
|
|
3726
|
+
}))
|
|
3716
3727
|
this.app.use((req, res, next) => {
|
|
3717
3728
|
const originalRedirect = res.redirect;
|
|
3718
3729
|
res.redirect = function (url) {
|
package/server/public/nav.js
CHANGED
|
@@ -1,12 +1,309 @@
|
|
|
1
1
|
document.addEventListener("DOMContentLoaded", () => {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
const newWindowButton = document.querySelector("#new-window");
|
|
3
|
+
if (newWindowButton) {
|
|
4
|
+
newWindowButton.addEventListener("click", (event) => {
|
|
5
|
+
const agent = document.body.getAttribute("data-agent");
|
|
5
6
|
if (agent === "electron") {
|
|
6
|
-
window.open("/", "_blank", "pinokio")
|
|
7
|
+
window.open("/", "_blank", "pinokio");
|
|
7
8
|
} else {
|
|
8
|
-
window.open("/", "_blank")
|
|
9
|
+
window.open("/", "_blank");
|
|
9
10
|
}
|
|
10
|
-
})
|
|
11
|
+
});
|
|
11
12
|
}
|
|
12
|
-
|
|
13
|
+
|
|
14
|
+
const header = document.querySelector("header.navheader");
|
|
15
|
+
const minimizeButton = document.querySelector("#minimize-header");
|
|
16
|
+
const homeLink = header ? header.querySelector(".home") : null;
|
|
17
|
+
if (!header || !minimizeButton || !homeLink) {
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const dispatchHeaderState = (minimized, detail = {}) => {
|
|
22
|
+
if (typeof window === "undefined" || typeof window.CustomEvent !== "function") {
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
const payload = { minimized, ...detail };
|
|
26
|
+
document.dispatchEvent(new CustomEvent("pinokio:header-state", { detail: payload }));
|
|
27
|
+
const aliasEvent = minimized ? "pinokio:header-minimized" : "pinokio:header-restored";
|
|
28
|
+
document.dispatchEvent(new CustomEvent(aliasEvent, { detail: { ...payload } }));
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
const headerTitle = header.querySelector("h1") || header;
|
|
32
|
+
let dragHandle = headerTitle.querySelector(".header-drag-handle");
|
|
33
|
+
if (!dragHandle) {
|
|
34
|
+
dragHandle = document.createElement("div");
|
|
35
|
+
dragHandle.className = "header-drag-handle";
|
|
36
|
+
dragHandle.setAttribute("aria-hidden", "true");
|
|
37
|
+
dragHandle.setAttribute("title", "Drag minimized header");
|
|
38
|
+
headerTitle.insertBefore(dragHandle, homeLink ? homeLink.nextSibling : headerTitle.firstChild);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const state = {
|
|
42
|
+
minimized: header.classList.contains("minimized"),
|
|
43
|
+
pointerId: null,
|
|
44
|
+
offsetX: 0,
|
|
45
|
+
offsetY: 0,
|
|
46
|
+
lastLeft: parseFloat(header.style.left) || 0,
|
|
47
|
+
lastTop: parseFloat(header.style.top) || 0,
|
|
48
|
+
hasCustomPosition: false,
|
|
49
|
+
originalPosition: {
|
|
50
|
+
top: header.style.top || "",
|
|
51
|
+
left: header.style.left || "",
|
|
52
|
+
right: header.style.right || "",
|
|
53
|
+
bottom: header.style.bottom || "",
|
|
54
|
+
},
|
|
55
|
+
transitionHandler: null,
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
dispatchHeaderState(state.minimized, { phase: "init" });
|
|
59
|
+
|
|
60
|
+
const MIN_MARGIN = 8;
|
|
61
|
+
|
|
62
|
+
const clampPosition = (left, top) => {
|
|
63
|
+
const rect = header.getBoundingClientRect();
|
|
64
|
+
const maxLeft = Math.max(0, window.innerWidth - rect.width);
|
|
65
|
+
const maxTop = Math.max(0, window.innerHeight - rect.height);
|
|
66
|
+
return {
|
|
67
|
+
left: Math.min(Math.max(0, left), maxLeft),
|
|
68
|
+
top: Math.min(Math.max(0, top), maxTop),
|
|
69
|
+
};
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
const applyPosition = (left, top) => {
|
|
73
|
+
header.style.left = `${left}px`;
|
|
74
|
+
header.style.top = `${top}px`;
|
|
75
|
+
header.style.right = "auto";
|
|
76
|
+
header.style.bottom = "auto";
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
const rememberOriginalPosition = () => {
|
|
80
|
+
state.originalPosition = {
|
|
81
|
+
top: header.style.top || "",
|
|
82
|
+
left: header.style.left || "",
|
|
83
|
+
right: header.style.right || "",
|
|
84
|
+
bottom: header.style.bottom || "",
|
|
85
|
+
};
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
const measureRect = (configureClone) => {
|
|
89
|
+
const clone = header.cloneNode(true);
|
|
90
|
+
clone.querySelectorAll("[id]").forEach((node) => node.removeAttribute("id"));
|
|
91
|
+
Object.assign(clone.style, {
|
|
92
|
+
transition: "none",
|
|
93
|
+
transform: "none",
|
|
94
|
+
position: "fixed",
|
|
95
|
+
visibility: "hidden",
|
|
96
|
+
pointerEvents: "none",
|
|
97
|
+
margin: "0",
|
|
98
|
+
left: "0",
|
|
99
|
+
top: "0",
|
|
100
|
+
right: "auto",
|
|
101
|
+
bottom: "auto",
|
|
102
|
+
width: "auto",
|
|
103
|
+
height: "auto",
|
|
104
|
+
});
|
|
105
|
+
document.body.appendChild(clone);
|
|
106
|
+
if (typeof configureClone === "function") {
|
|
107
|
+
configureClone(clone);
|
|
108
|
+
}
|
|
109
|
+
clone.style.right = "auto";
|
|
110
|
+
clone.style.bottom = "auto";
|
|
111
|
+
const rect = clone.getBoundingClientRect();
|
|
112
|
+
clone.remove();
|
|
113
|
+
return rect;
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
const stopTransition = () => {
|
|
117
|
+
if (state.transitionHandler) {
|
|
118
|
+
header.removeEventListener("transitionend", state.transitionHandler);
|
|
119
|
+
state.transitionHandler = null;
|
|
120
|
+
}
|
|
121
|
+
header.classList.remove("transitioning");
|
|
122
|
+
header.style.transition = "";
|
|
123
|
+
header.style.transform = "";
|
|
124
|
+
header.style.transformOrigin = "";
|
|
125
|
+
header.style.opacity = "";
|
|
126
|
+
header.style.willChange = "";
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
const minimize = () => {
|
|
130
|
+
if (state.minimized || header.classList.contains("transitioning")) {
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
rememberOriginalPosition();
|
|
135
|
+
|
|
136
|
+
const firstRect = header.getBoundingClientRect();
|
|
137
|
+
const minimizedSize = measureRect((clone) => {
|
|
138
|
+
clone.classList.add("minimized");
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
const defaultLeft = Math.max(MIN_MARGIN, window.innerWidth - minimizedSize.width - MIN_MARGIN);
|
|
142
|
+
const defaultTop = Math.max(MIN_MARGIN, window.innerHeight - minimizedSize.height - MIN_MARGIN);
|
|
143
|
+
const targetLeft = state.hasCustomPosition ? state.lastLeft : defaultLeft;
|
|
144
|
+
const targetTop = state.hasCustomPosition ? state.lastTop : defaultTop;
|
|
145
|
+
|
|
146
|
+
state.lastLeft = targetLeft;
|
|
147
|
+
state.lastTop = targetTop;
|
|
148
|
+
|
|
149
|
+
stopTransition();
|
|
150
|
+
|
|
151
|
+
header.classList.add("minimized");
|
|
152
|
+
applyPosition(targetLeft, targetTop);
|
|
153
|
+
|
|
154
|
+
dispatchHeaderState(true, { phase: "start" });
|
|
155
|
+
|
|
156
|
+
const lastRect = header.getBoundingClientRect();
|
|
157
|
+
const deltaX = firstRect.left - lastRect.left;
|
|
158
|
+
const deltaY = firstRect.top - lastRect.top;
|
|
159
|
+
const scaleX = firstRect.width / lastRect.width;
|
|
160
|
+
const scaleY = firstRect.height / lastRect.height;
|
|
161
|
+
|
|
162
|
+
header.style.transition = "none";
|
|
163
|
+
header.style.transformOrigin = "top left";
|
|
164
|
+
header.style.transform = `translate(${deltaX}px, ${deltaY}px) scale(${scaleX}, ${scaleY})`;
|
|
165
|
+
header.style.willChange = "transform";
|
|
166
|
+
|
|
167
|
+
header.offsetWidth;
|
|
168
|
+
|
|
169
|
+
header.classList.add("transitioning");
|
|
170
|
+
header.style.transition = "transform 520ms cubic-bezier(0.22, 1, 0.36, 1)";
|
|
171
|
+
header.style.transform = "";
|
|
172
|
+
|
|
173
|
+
state.transitionHandler = (event) => {
|
|
174
|
+
if (event.propertyName !== "transform") {
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
header.removeEventListener("transitionend", state.transitionHandler);
|
|
178
|
+
state.transitionHandler = null;
|
|
179
|
+
stopTransition();
|
|
180
|
+
state.minimized = true;
|
|
181
|
+
dispatchHeaderState(true, { phase: "settled" });
|
|
182
|
+
};
|
|
183
|
+
|
|
184
|
+
header.addEventListener("transitionend", state.transitionHandler);
|
|
185
|
+
};
|
|
186
|
+
|
|
187
|
+
const restore = () => {
|
|
188
|
+
if (!state.minimized || header.classList.contains("transitioning")) {
|
|
189
|
+
return;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
const firstRect = header.getBoundingClientRect();
|
|
193
|
+
|
|
194
|
+
stopTransition();
|
|
195
|
+
|
|
196
|
+
header.classList.add("transitioning");
|
|
197
|
+
header.style.willChange = "transform";
|
|
198
|
+
header.style.transition = "none";
|
|
199
|
+
header.style.transformOrigin = "top left";
|
|
200
|
+
|
|
201
|
+
header.classList.remove("minimized");
|
|
202
|
+
header.style.left = state.originalPosition.left;
|
|
203
|
+
header.style.top = state.originalPosition.top;
|
|
204
|
+
header.style.right = state.originalPosition.right;
|
|
205
|
+
header.style.bottom = state.originalPosition.bottom;
|
|
206
|
+
|
|
207
|
+
dispatchHeaderState(false, { phase: "start" });
|
|
208
|
+
|
|
209
|
+
const lastRect = header.getBoundingClientRect();
|
|
210
|
+
const deltaX = firstRect.left - lastRect.left;
|
|
211
|
+
const deltaY = firstRect.top - lastRect.top;
|
|
212
|
+
const scaleX = firstRect.width / lastRect.width;
|
|
213
|
+
const scaleY = firstRect.height / lastRect.height;
|
|
214
|
+
|
|
215
|
+
header.style.transform = `translate(${deltaX}px, ${deltaY}px) scale(${scaleX}, ${scaleY})`;
|
|
216
|
+
|
|
217
|
+
header.offsetWidth;
|
|
218
|
+
|
|
219
|
+
header.style.transition = "transform 560ms cubic-bezier(0.18, 0.85, 0.4, 1)";
|
|
220
|
+
header.style.transform = "";
|
|
221
|
+
|
|
222
|
+
state.transitionHandler = (event) => {
|
|
223
|
+
if (event.propertyName !== "transform") {
|
|
224
|
+
return;
|
|
225
|
+
}
|
|
226
|
+
header.removeEventListener("transitionend", state.transitionHandler);
|
|
227
|
+
state.transitionHandler = null;
|
|
228
|
+
stopTransition();
|
|
229
|
+
state.minimized = false;
|
|
230
|
+
state.hasCustomPosition = false;
|
|
231
|
+
state.lastLeft = parseFloat(header.style.left) || 0;
|
|
232
|
+
state.lastTop = parseFloat(header.style.top) || 0;
|
|
233
|
+
dispatchHeaderState(false, { phase: "settled" });
|
|
234
|
+
};
|
|
235
|
+
|
|
236
|
+
header.addEventListener("transitionend", state.transitionHandler);
|
|
237
|
+
};
|
|
238
|
+
|
|
239
|
+
minimizeButton.addEventListener("click", (event) => {
|
|
240
|
+
event.preventDefault();
|
|
241
|
+
minimize();
|
|
242
|
+
});
|
|
243
|
+
|
|
244
|
+
homeLink.addEventListener("click", (event) => {
|
|
245
|
+
if (!state.minimized) {
|
|
246
|
+
return;
|
|
247
|
+
}
|
|
248
|
+
event.preventDefault();
|
|
249
|
+
restore();
|
|
250
|
+
});
|
|
251
|
+
|
|
252
|
+
const onPointerDown = (event) => {
|
|
253
|
+
if (!state.minimized || header.classList.contains("transitioning")) {
|
|
254
|
+
return;
|
|
255
|
+
}
|
|
256
|
+
state.pointerId = event.pointerId;
|
|
257
|
+
const rect = header.getBoundingClientRect();
|
|
258
|
+
state.offsetX = event.clientX - rect.left;
|
|
259
|
+
state.offsetY = event.clientY - rect.top;
|
|
260
|
+
if (typeof dragHandle.setPointerCapture === "function") {
|
|
261
|
+
try {
|
|
262
|
+
dragHandle.setPointerCapture(event.pointerId);
|
|
263
|
+
} catch (error) {}
|
|
264
|
+
}
|
|
265
|
+
dragHandle.classList.add("dragging");
|
|
266
|
+
event.preventDefault();
|
|
267
|
+
};
|
|
268
|
+
|
|
269
|
+
const onPointerMove = (event) => {
|
|
270
|
+
if (!state.minimized || state.pointerId !== event.pointerId) {
|
|
271
|
+
return;
|
|
272
|
+
}
|
|
273
|
+
const left = event.clientX - state.offsetX;
|
|
274
|
+
const top = event.clientY - state.offsetY;
|
|
275
|
+
const clamped = clampPosition(left, top);
|
|
276
|
+
state.lastLeft = clamped.left;
|
|
277
|
+
state.lastTop = clamped.top;
|
|
278
|
+
state.hasCustomPosition = true;
|
|
279
|
+
applyPosition(clamped.left, clamped.top);
|
|
280
|
+
};
|
|
281
|
+
|
|
282
|
+
const onPointerEnd = (event) => {
|
|
283
|
+
if (state.pointerId !== event.pointerId) {
|
|
284
|
+
return;
|
|
285
|
+
}
|
|
286
|
+
if (typeof dragHandle.releasePointerCapture === "function") {
|
|
287
|
+
try {
|
|
288
|
+
dragHandle.releasePointerCapture(event.pointerId);
|
|
289
|
+
} catch (error) {}
|
|
290
|
+
}
|
|
291
|
+
dragHandle.classList.remove("dragging");
|
|
292
|
+
state.pointerId = null;
|
|
293
|
+
};
|
|
294
|
+
|
|
295
|
+
dragHandle.addEventListener("pointerdown", onPointerDown);
|
|
296
|
+
dragHandle.addEventListener("pointermove", onPointerMove);
|
|
297
|
+
dragHandle.addEventListener("pointerup", onPointerEnd);
|
|
298
|
+
dragHandle.addEventListener("pointercancel", onPointerEnd);
|
|
299
|
+
|
|
300
|
+
window.addEventListener("resize", () => {
|
|
301
|
+
if (!state.minimized || header.classList.contains("transitioning")) {
|
|
302
|
+
return;
|
|
303
|
+
}
|
|
304
|
+
const { left, top } = clampPosition(state.lastLeft, state.lastTop);
|
|
305
|
+
state.lastLeft = left;
|
|
306
|
+
state.lastTop = top;
|
|
307
|
+
applyPosition(left, top);
|
|
308
|
+
});
|
|
309
|
+
});
|
package/server/public/style.css
CHANGED
|
@@ -2482,3 +2482,85 @@ body.dark #dropdown-portal .dropdown-content .btn2 {
|
|
|
2482
2482
|
border-radius: 10px;
|
|
2483
2483
|
background: white;
|
|
2484
2484
|
}
|
|
2485
|
+
|
|
2486
|
+
|
|
2487
|
+
header.navheader.minimized {
|
|
2488
|
+
position: fixed;
|
|
2489
|
+
right: auto;
|
|
2490
|
+
bottom: auto;
|
|
2491
|
+
width: auto;
|
|
2492
|
+
height: auto;
|
|
2493
|
+
max-height: none;
|
|
2494
|
+
padding: 4px 8px;
|
|
2495
|
+
border-radius: 12px;
|
|
2496
|
+
background: var(--light-nav-bg);
|
|
2497
|
+
box-shadow: 0 8px 18px rgba(0, 0, 0, 0.14), 0 2px 6px rgba(0, 0, 0, 0.08);
|
|
2498
|
+
display: inline-flex;
|
|
2499
|
+
align-items: center;
|
|
2500
|
+
overflow: visible;
|
|
2501
|
+
z-index: 1000000;
|
|
2502
|
+
}
|
|
2503
|
+
body.dark header.navheader.minimized {
|
|
2504
|
+
background: var(--dark-nav-bg);
|
|
2505
|
+
box-shadow: 0 12px 26px rgba(0, 0, 0, 0.55), 0 0 1px rgba(255, 255, 255, 0.15);
|
|
2506
|
+
}
|
|
2507
|
+
header.navheader.minimized h1 {
|
|
2508
|
+
display: flex;
|
|
2509
|
+
align-items: center;
|
|
2510
|
+
gap: 8px;
|
|
2511
|
+
margin: 0;
|
|
2512
|
+
padding: 0;
|
|
2513
|
+
height: auto;
|
|
2514
|
+
overflow: visible;
|
|
2515
|
+
}
|
|
2516
|
+
header.navheader.minimized h1 > *:not(.home):not(.header-drag-handle) {
|
|
2517
|
+
display: none !important;
|
|
2518
|
+
}
|
|
2519
|
+
header.navheader .header-drag-handle {
|
|
2520
|
+
display: none;
|
|
2521
|
+
position: relative;
|
|
2522
|
+
cursor: grab;
|
|
2523
|
+
user-select: none;
|
|
2524
|
+
touch-action: none;
|
|
2525
|
+
}
|
|
2526
|
+
header.navheader .header-drag-handle::before {
|
|
2527
|
+
content: "";
|
|
2528
|
+
display: block;
|
|
2529
|
+
width: 6px;
|
|
2530
|
+
height: 18px;
|
|
2531
|
+
border-radius: 3px;
|
|
2532
|
+
opacity: 0.45;
|
|
2533
|
+
background-image: repeating-linear-gradient(to bottom, rgba(0, 0, 0, 0.5) 0 1px, transparent 1px 4px);
|
|
2534
|
+
transition: opacity 0.2s ease;
|
|
2535
|
+
}
|
|
2536
|
+
body.dark header.navheader .header-drag-handle::before {
|
|
2537
|
+
background-image: repeating-linear-gradient(to bottom, rgba(255, 255, 255, 0.55) 0 1px, transparent 1px 4px);
|
|
2538
|
+
opacity: 0.35;
|
|
2539
|
+
}
|
|
2540
|
+
header.navheader.minimized .header-drag-handle {
|
|
2541
|
+
display: block;
|
|
2542
|
+
}
|
|
2543
|
+
header.navheader.minimized:hover .header-drag-handle::before {
|
|
2544
|
+
opacity: 0.7;
|
|
2545
|
+
}
|
|
2546
|
+
header.navheader.minimized .header-drag-handle.dragging {
|
|
2547
|
+
cursor: grabbing;
|
|
2548
|
+
}
|
|
2549
|
+
header.navheader.minimized .header-drag-handle.dragging::before {
|
|
2550
|
+
opacity: 0.85;
|
|
2551
|
+
}
|
|
2552
|
+
header.navheader.minimized .home {
|
|
2553
|
+
display: flex;
|
|
2554
|
+
align-items: center;
|
|
2555
|
+
position: static;
|
|
2556
|
+
padding: 0;
|
|
2557
|
+
}
|
|
2558
|
+
header.navheader.minimized .home .icon {
|
|
2559
|
+
width: 24px;
|
|
2560
|
+
height: 24px;
|
|
2561
|
+
}
|
|
2562
|
+
|
|
2563
|
+
|
|
2564
|
+
header.navheader.transitioning {
|
|
2565
|
+
pointer-events: none;
|
|
2566
|
+
}
|
package/server/views/app.ejs
CHANGED
|
@@ -180,6 +180,20 @@ body.dark .appcanvas_filler {
|
|
|
180
180
|
--sidebar-tab-outline: var(--pinokio-sidebar-tabbar-border);
|
|
181
181
|
}
|
|
182
182
|
|
|
183
|
+
.appcanvas > aside.appcanvas-aside-animating {
|
|
184
|
+
will-change: height, opacity;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
.appcanvas > aside.appcanvas-aside-collapsed {
|
|
188
|
+
height: 0 !important;
|
|
189
|
+
opacity: 0;
|
|
190
|
+
pointer-events: none;
|
|
191
|
+
padding-top: 0;
|
|
192
|
+
padding-bottom: 0;
|
|
193
|
+
margin-top: 0;
|
|
194
|
+
margin-bottom: 0;
|
|
195
|
+
}
|
|
196
|
+
|
|
183
197
|
/*
|
|
184
198
|
body.dark .appcanvas > aside {
|
|
185
199
|
background: var(--pinokio-sidebar-tabbar-bg);
|
|
@@ -404,6 +418,9 @@ body.dark .appcanvas > aside .header-item.selected {
|
|
|
404
418
|
border-bottom: none;
|
|
405
419
|
z-index: 1;
|
|
406
420
|
}
|
|
421
|
+
header.navheader.minimized + .appcanvas > aside .menu-container {
|
|
422
|
+
padding: 8px 0 0;
|
|
423
|
+
}
|
|
407
424
|
|
|
408
425
|
main {
|
|
409
426
|
flex-grow: 1;
|
|
@@ -2723,6 +2740,9 @@ body.dark {
|
|
|
2723
2740
|
.appcanvas {
|
|
2724
2741
|
margin-left: 55px;
|
|
2725
2742
|
}
|
|
2743
|
+
header.navheader.minimized + .appcanvas {
|
|
2744
|
+
margin-left: 0;
|
|
2745
|
+
}
|
|
2726
2746
|
main, iframe.mainframe {
|
|
2727
2747
|
padding-left: 0;
|
|
2728
2748
|
}
|
|
@@ -2822,6 +2842,9 @@ body.dark {
|
|
|
2822
2842
|
<a class='btn2' href="/rows" data-tippy-content="split into 2 rows">
|
|
2823
2843
|
<div><i class="fa-solid fa-table-columns fa-rotate-270"></i></div>
|
|
2824
2844
|
</a>
|
|
2845
|
+
<button class='btn2' id='minimize-header' data-tippy-content="minimize header" title='minimize header'>
|
|
2846
|
+
<div><i class="fa-solid fa-expand"></i></div>
|
|
2847
|
+
</button>
|
|
2825
2848
|
<button class='btn2' id='new-window' data-tippy-content="open a new window" title='open a new window' data-agent="<%=agent%>">
|
|
2826
2849
|
<div><i class="fa-solid fa-plus"></i></div>
|
|
2827
2850
|
</button>
|
|
@@ -8545,6 +8568,153 @@ body.dark {
|
|
|
8545
8568
|
|
|
8546
8569
|
</script>
|
|
8547
8570
|
<% } %>
|
|
8571
|
+
<script>
|
|
8572
|
+
(() => {
|
|
8573
|
+
const aside = document.querySelector(".appcanvas > aside")
|
|
8574
|
+
if (!aside) {
|
|
8575
|
+
return
|
|
8576
|
+
}
|
|
8577
|
+
|
|
8578
|
+
const collapsedClass = "appcanvas-aside-collapsed"
|
|
8579
|
+
const animatingClass = "appcanvas-aside-animating"
|
|
8580
|
+
const collapseDuration = 420
|
|
8581
|
+
const collapseEasing = "cubic-bezier(0.22, 1, 0.36, 1)"
|
|
8582
|
+
const expandEasing = "cubic-bezier(0.18, 0.85, 0.4, 1)"
|
|
8583
|
+
|
|
8584
|
+
let transitionHandler = null
|
|
8585
|
+
let queuedFrame = null
|
|
8586
|
+
|
|
8587
|
+
const clearAnimation = () => {
|
|
8588
|
+
if (transitionHandler) {
|
|
8589
|
+
aside.removeEventListener("transitionend", transitionHandler)
|
|
8590
|
+
transitionHandler = null
|
|
8591
|
+
}
|
|
8592
|
+
if (queuedFrame !== null) {
|
|
8593
|
+
cancelAnimationFrame(queuedFrame)
|
|
8594
|
+
queuedFrame = null
|
|
8595
|
+
}
|
|
8596
|
+
aside.classList.remove(animatingClass)
|
|
8597
|
+
aside.style.transition = ""
|
|
8598
|
+
aside.style.height = ""
|
|
8599
|
+
aside.style.opacity = ""
|
|
8600
|
+
}
|
|
8601
|
+
|
|
8602
|
+
const finish = (minimized) => {
|
|
8603
|
+
aside.classList.toggle(collapsedClass, minimized)
|
|
8604
|
+
aside.classList.remove(animatingClass)
|
|
8605
|
+
aside.style.transition = ""
|
|
8606
|
+
aside.style.height = ""
|
|
8607
|
+
aside.style.opacity = ""
|
|
8608
|
+
aside.dataset.asideState = minimized ? "collapsed" : "expanded"
|
|
8609
|
+
}
|
|
8610
|
+
|
|
8611
|
+
const collapse = (immediate) => {
|
|
8612
|
+
if (aside.dataset.asideState === "collapsed" && !immediate) {
|
|
8613
|
+
return
|
|
8614
|
+
}
|
|
8615
|
+
clearAnimation()
|
|
8616
|
+
if (immediate) {
|
|
8617
|
+
finish(true)
|
|
8618
|
+
return
|
|
8619
|
+
}
|
|
8620
|
+
const startHeight = aside.getBoundingClientRect().height
|
|
8621
|
+
if (startHeight <= 0.5) {
|
|
8622
|
+
finish(true)
|
|
8623
|
+
return
|
|
8624
|
+
}
|
|
8625
|
+
|
|
8626
|
+
aside.classList.add(animatingClass)
|
|
8627
|
+
aside.style.height = `${startHeight}px`
|
|
8628
|
+
aside.style.opacity = getComputedStyle(aside).opacity || "1"
|
|
8629
|
+
aside.dataset.asideState = "animating"
|
|
8630
|
+
|
|
8631
|
+
queuedFrame = requestAnimationFrame(() => {
|
|
8632
|
+
queuedFrame = null
|
|
8633
|
+
aside.style.transition = `height ${collapseDuration}ms ${collapseEasing}, opacity ${collapseDuration - 120}ms ease`
|
|
8634
|
+
aside.style.height = "0px"
|
|
8635
|
+
aside.style.opacity = "0"
|
|
8636
|
+
})
|
|
8637
|
+
|
|
8638
|
+
transitionHandler = (event) => {
|
|
8639
|
+
if (event.target !== aside || event.propertyName !== "height") {
|
|
8640
|
+
return
|
|
8641
|
+
}
|
|
8642
|
+
aside.removeEventListener("transitionend", transitionHandler)
|
|
8643
|
+
transitionHandler = null
|
|
8644
|
+
finish(true)
|
|
8645
|
+
}
|
|
8646
|
+
aside.addEventListener("transitionend", transitionHandler)
|
|
8647
|
+
}
|
|
8648
|
+
|
|
8649
|
+
const expand = (immediate) => {
|
|
8650
|
+
if (aside.dataset.asideState === "expanded" && !immediate) {
|
|
8651
|
+
return
|
|
8652
|
+
}
|
|
8653
|
+
clearAnimation()
|
|
8654
|
+
if (immediate) {
|
|
8655
|
+
finish(false)
|
|
8656
|
+
return
|
|
8657
|
+
}
|
|
8658
|
+
|
|
8659
|
+
aside.classList.remove(collapsedClass)
|
|
8660
|
+
const targetHeight = aside.scrollHeight
|
|
8661
|
+
aside.classList.add(animatingClass)
|
|
8662
|
+
aside.style.height = "0px"
|
|
8663
|
+
aside.style.opacity = "0"
|
|
8664
|
+
aside.dataset.asideState = "animating"
|
|
8665
|
+
|
|
8666
|
+
aside.offsetHeight
|
|
8667
|
+
|
|
8668
|
+
queuedFrame = requestAnimationFrame(() => {
|
|
8669
|
+
queuedFrame = null
|
|
8670
|
+
aside.style.transition = `height ${collapseDuration}ms ${expandEasing}, opacity ${collapseDuration - 140}ms ease`
|
|
8671
|
+
aside.style.height = `${targetHeight}px`
|
|
8672
|
+
aside.style.opacity = ""
|
|
8673
|
+
})
|
|
8674
|
+
|
|
8675
|
+
transitionHandler = (event) => {
|
|
8676
|
+
if (event.target !== aside || event.propertyName !== "height") {
|
|
8677
|
+
return
|
|
8678
|
+
}
|
|
8679
|
+
aside.removeEventListener("transitionend", transitionHandler)
|
|
8680
|
+
transitionHandler = null
|
|
8681
|
+
finish(false)
|
|
8682
|
+
}
|
|
8683
|
+
aside.addEventListener("transitionend", transitionHandler)
|
|
8684
|
+
}
|
|
8685
|
+
|
|
8686
|
+
const setAside = (minimized, immediate) => {
|
|
8687
|
+
if (minimized) {
|
|
8688
|
+
collapse(immediate)
|
|
8689
|
+
} else {
|
|
8690
|
+
expand(immediate)
|
|
8691
|
+
}
|
|
8692
|
+
}
|
|
8693
|
+
|
|
8694
|
+
const header = document.querySelector("header.navheader")
|
|
8695
|
+
const initialMinimized = !!(header && header.classList.contains("minimized"))
|
|
8696
|
+
setAside(initialMinimized, true)
|
|
8697
|
+
|
|
8698
|
+
document.addEventListener("pinokio:header-state", (event) => {
|
|
8699
|
+
if (!event || !event.detail) {
|
|
8700
|
+
return
|
|
8701
|
+
}
|
|
8702
|
+
const { minimized, phase } = event.detail
|
|
8703
|
+
if (phase === "init") {
|
|
8704
|
+
setAside(!!minimized, true)
|
|
8705
|
+
return
|
|
8706
|
+
}
|
|
8707
|
+
if (phase === "start") {
|
|
8708
|
+
setAside(!!minimized, false)
|
|
8709
|
+
return
|
|
8710
|
+
}
|
|
8711
|
+
if (phase === "settled") {
|
|
8712
|
+
clearAnimation()
|
|
8713
|
+
finish(!!minimized)
|
|
8714
|
+
}
|
|
8715
|
+
})
|
|
8716
|
+
})()
|
|
8717
|
+
</script>
|
|
8548
8718
|
<script src="/tab-idle-notifier.js"></script>
|
|
8549
8719
|
</body>
|
|
8550
8720
|
</html>
|
|
@@ -205,6 +205,9 @@ pre {
|
|
|
205
205
|
<a class='btn2' href="/rows" data-tippy-content="split into 2 rows">
|
|
206
206
|
<div><i class="fa-solid fa-table-columns fa-rotate-270"></i></div>
|
|
207
207
|
</a>
|
|
208
|
+
<button class='btn2' id='minimize-header' data-tippy-content="minimize header" title='minimize header'>
|
|
209
|
+
<div><i class="fa-solid fa-expand"></i></div>
|
|
210
|
+
</button>
|
|
208
211
|
<button class='btn2' id='new-window' data-tippy-content="open a new window" title='open a new window' data-agent="<%=agent%>">
|
|
209
212
|
<div><i class="fa-solid fa-plus"></i></div>
|
|
210
213
|
</button>
|
package/server/views/connect.ejs
CHANGED
|
@@ -830,6 +830,9 @@ document.addEventListener('DOMContentLoaded', function() {
|
|
|
830
830
|
<a class='btn2' href="/rows" data-tippy-content="split into 2 rows">
|
|
831
831
|
<div><i class="fa-solid fa-table-columns fa-rotate-270"></i></div>
|
|
832
832
|
</a>
|
|
833
|
+
<button class='btn2' id='minimize-header' data-tippy-content="minimize header" title='minimize header'>
|
|
834
|
+
<div><i class="fa-solid fa-expand"></i></div>
|
|
835
|
+
</button>
|
|
833
836
|
<button class='btn2' id='new-window' data-tippy-content="open a new window" title='open a new window' data-agent="<%=agent%>">
|
|
834
837
|
<div><i class="fa-solid fa-plus"></i></div>
|
|
835
838
|
</button>
|
|
@@ -344,6 +344,9 @@ iframe {
|
|
|
344
344
|
<a class='btn2' href="/rows" data-tippy-content="split into 2 rows">
|
|
345
345
|
<div><i class="fa-solid fa-table-columns fa-rotate-270"></i></div>
|
|
346
346
|
</a>
|
|
347
|
+
<button class='btn2' id='minimize-header' data-tippy-content="minimize header" title='minimize header'>
|
|
348
|
+
<div><i class="fa-solid fa-expand"></i></div>
|
|
349
|
+
</button>
|
|
347
350
|
<button class='btn2' id='new-window' data-tippy-content="open a new window" title='open a new window' data-agent="<%=agent%>">
|
|
348
351
|
<div><i class="fa-solid fa-plus"></i></div>
|
|
349
352
|
</button>
|
|
@@ -133,6 +133,9 @@ body.frozen {
|
|
|
133
133
|
<a class='btn2' href="/rows" data-tippy-content="split into 2 rows">
|
|
134
134
|
<div><i class="fa-solid fa-table-columns fa-rotate-270"></i></div>
|
|
135
135
|
</a>
|
|
136
|
+
<button class='btn2' id='minimize-header' data-tippy-content="minimize header" title='minimize header'>
|
|
137
|
+
<div><i class="fa-solid fa-expand"></i></div>
|
|
138
|
+
</button>
|
|
136
139
|
<button class='btn2' id='new-window' data-tippy-content="open a new window" title='open a new window' data-agent="<%=agent%>">
|
|
137
140
|
<div><i class="fa-solid fa-plus"></i></div>
|
|
138
141
|
</button>
|
package/server/views/explore.ejs
CHANGED
|
@@ -134,6 +134,9 @@ body main iframe {
|
|
|
134
134
|
<a class='btn2' href="/rows" data-tippy-content="split into 2 rows">
|
|
135
135
|
<div><i class="fa-solid fa-table-columns fa-rotate-270"></i></div>
|
|
136
136
|
</a>
|
|
137
|
+
<button class='btn2' id='minimize-header' data-tippy-content="minimize header" title='minimize header'>
|
|
138
|
+
<div><i class="fa-solid fa-expand"></i></div>
|
|
139
|
+
</button>
|
|
137
140
|
<button class='btn2' id='new-window' data-tippy-content="open a new window" title='open a new window' data-agent="<%=agent%>">
|
|
138
141
|
<div><i class="fa-solid fa-plus"></i></div>
|
|
139
142
|
</button>
|
package/server/views/form.ejs
CHANGED
|
@@ -167,6 +167,9 @@ document.addEventListener("DOMContentLoaded", async () => {
|
|
|
167
167
|
<a class='btn2' href="/rows" data-tippy-content="split into 2 rows">
|
|
168
168
|
<div><i class="fa-solid fa-table-columns fa-rotate-270"></i></div>
|
|
169
169
|
</a>
|
|
170
|
+
<button class='btn2' id='minimize-header' data-tippy-content="minimize header" title='minimize header'>
|
|
171
|
+
<div><i class="fa-solid fa-expand"></i></div>
|
|
172
|
+
</button>
|
|
170
173
|
<button class='btn2' id='new-window' data-tippy-content="open a new window" title='open a new window' data-agent="<%=agent%>">
|
|
171
174
|
<div><i class="fa-solid fa-plus"></i></div>
|
|
172
175
|
</button>
|
package/server/views/frame.ejs
CHANGED
|
@@ -63,6 +63,9 @@ main iframe {
|
|
|
63
63
|
<a class='btn2' href="/rows" data-tippy-content="split into 2 rows">
|
|
64
64
|
<div><i class="fa-solid fa-table-columns fa-rotate-270"></i></div>
|
|
65
65
|
</a>
|
|
66
|
+
<button class='btn2' id='minimize-header' data-tippy-content="minimize header" title='minimize header'>
|
|
67
|
+
<div><i class="fa-solid fa-expand"></i></div>
|
|
68
|
+
</button>
|
|
66
69
|
<button class='btn2' id='new-window' data-tippy-content="open a new window" title='open a new window' data-agent="<%=agent%>">
|
|
67
70
|
<div><i class="fa-solid fa-plus"></i></div>
|
|
68
71
|
</button>
|
package/server/views/github.ejs
CHANGED
|
@@ -246,6 +246,9 @@ ol {
|
|
|
246
246
|
<a class='btn2' href="/rows" data-tippy-content="split into 2 rows">
|
|
247
247
|
<div><i class="fa-solid fa-table-columns fa-rotate-270"></i></div>
|
|
248
248
|
</a>
|
|
249
|
+
<button class='btn2' id='minimize-header' data-tippy-content="minimize header" title='minimize header'>
|
|
250
|
+
<div><i class="fa-solid fa-expand"></i></div>
|
|
251
|
+
</button>
|
|
249
252
|
<button class='btn2' id='new-window' data-tippy-content="open a new window" title='open a new window' data-agent="<%=agent%>">
|
|
250
253
|
<div><i class="fa-solid fa-plus"></i></div>
|
|
251
254
|
</button>
|
package/server/views/help.ejs
CHANGED
|
@@ -267,6 +267,9 @@ body.dark .item .tile .badge {
|
|
|
267
267
|
<a class='btn2' href="/rows" data-tippy-content="split into 2 rows">
|
|
268
268
|
<div><i class="fa-solid fa-table-columns fa-rotate-270"></i></div>
|
|
269
269
|
</a>
|
|
270
|
+
<button class='btn2' id='minimize-header' data-tippy-content="minimize header" title='minimize header'>
|
|
271
|
+
<div><i class="fa-solid fa-expand"></i></div>
|
|
272
|
+
</button>
|
|
270
273
|
<button class='btn2' id='new-window' data-tippy-content="open a new window" title='open a new window' data-agent="<%=agent%>">
|
|
271
274
|
<div><i class="fa-solid fa-plus"></i></div>
|
|
272
275
|
</button>
|
package/server/views/index.ejs
CHANGED
|
@@ -435,6 +435,9 @@ body.dark aside .current.selected {
|
|
|
435
435
|
<a class='btn2' href="/rows" data-tippy-content="split into 2 rows">
|
|
436
436
|
<div><i class="fa-solid fa-table-columns fa-rotate-270"></i></div>
|
|
437
437
|
</a>
|
|
438
|
+
<button class='btn2' id='minimize-header' data-tippy-content="minimize header" title='minimize header'>
|
|
439
|
+
<div><i class="fa-solid fa-expand"></i></div>
|
|
440
|
+
</button>
|
|
438
441
|
<button class='btn2' id='new-window' data-tippy-content="open a new window" title='open a new window' data-agent="<%=agent%>">
|
|
439
442
|
<div><i class="fa-solid fa-plus"></i></div>
|
|
440
443
|
</button>
|
package/server/views/index2.ejs
CHANGED
|
@@ -272,6 +272,9 @@ body.dark .open-menu, body.dark .browse {
|
|
|
272
272
|
<button class='btn2' id='genlog'><div><i class="fa-solid fa-laptop-code"></i></div><div>Logs</div></button>
|
|
273
273
|
<a id='downloadlogs' download class='hidden btn2' href="/pinokio/logs.zip"><div><i class="fa-solid fa-download"></i></div><div>Download logs</div></a>
|
|
274
274
|
<a class='btn2' href="/home?mode=settings"><div><i class="fa-solid fa-gear"></i></div><div>Settings</div></a>
|
|
275
|
+
<button class='btn2' id='minimize-header' data-tippy-content="minimize header" title='minimize header'>
|
|
276
|
+
<div><i class="fa-solid fa-expand"></i></div>
|
|
277
|
+
</button>
|
|
275
278
|
<button id='new-window' title='open a new window' class='btn2' data-agent="<%=agent%>"><div><i class="fa-solid fa-plus"></i></div><div>Window</div></button>
|
|
276
279
|
</div>
|
|
277
280
|
<% } %>
|
|
@@ -1532,6 +1532,9 @@ body.dark .ace-editor {
|
|
|
1532
1532
|
<a class='btn2' href="/rows" data-tippy-content="split into 2 rows">
|
|
1533
1533
|
<div><i class="fa-solid fa-table-columns fa-rotate-270"></i></div>
|
|
1534
1534
|
</a>
|
|
1535
|
+
<button class='btn2' id='minimize-header' data-tippy-content="minimize header" title='minimize header'>
|
|
1536
|
+
<div><i class="fa-solid fa-expand"></i></div>
|
|
1537
|
+
</button>
|
|
1535
1538
|
<button class='btn2' id='new-window' data-tippy-content="open a new window" title='open a new window' data-agent="<%=agent%>">
|
|
1536
1539
|
<div><i class="fa-solid fa-plus"></i></div>
|
|
1537
1540
|
</button>
|
package/server/views/mini.ejs
CHANGED
|
@@ -767,6 +767,9 @@ body.dark .appcanvas {
|
|
|
767
767
|
<a class='btn2' href="/rows" data-tippy-content="split into 2 rows">
|
|
768
768
|
<div><i class="fa-solid fa-table-columns fa-rotate-270"></i></div>
|
|
769
769
|
</a>
|
|
770
|
+
<button class='btn2' id='minimize-header' data-tippy-content="minimize header" title='minimize header'>
|
|
771
|
+
<div><i class="fa-solid fa-expand"></i></div>
|
|
772
|
+
</button>
|
|
770
773
|
<button class='btn2' id='new-window' data-tippy-content="open a new window" title='open a new window' data-agent="<%=agent%>">
|
|
771
774
|
<div><i class="fa-solid fa-plus"></i></div>
|
|
772
775
|
</button>
|
package/server/views/net.ejs
CHANGED
|
@@ -553,6 +553,9 @@ document.addEventListener('DOMContentLoaded', function() {
|
|
|
553
553
|
<a class='btn2' href="/rows" data-tippy-content="split into 2 rows">
|
|
554
554
|
<div><i class="fa-solid fa-table-columns fa-rotate-270"></i></div>
|
|
555
555
|
</a>
|
|
556
|
+
<button class='btn2' id='minimize-header' data-tippy-content="minimize header" title='minimize header'>
|
|
557
|
+
<div><i class="fa-solid fa-expand"></i></div>
|
|
558
|
+
</button>
|
|
556
559
|
<button class='btn2' id='new-window' data-tippy-content="open a new window" title='open a new window' data-agent="<%=agent%>">
|
|
557
560
|
<div><i class="fa-solid fa-plus"></i></div>
|
|
558
561
|
</button>
|
package/server/views/network.ejs
CHANGED
|
@@ -1066,6 +1066,9 @@ document.addEventListener('DOMContentLoaded', function() {
|
|
|
1066
1066
|
<a class='btn2' href="/rows" data-tippy-content="split into 2 rows">
|
|
1067
1067
|
<div><i class="fa-solid fa-table-columns fa-rotate-270"></i></div>
|
|
1068
1068
|
</a>
|
|
1069
|
+
<button class='btn2' id='minimize-header' data-tippy-content="minimize header" title='minimize header'>
|
|
1070
|
+
<div><i class="fa-solid fa-expand"></i></div>
|
|
1071
|
+
</button>
|
|
1069
1072
|
<button class='btn2' id='new-window' data-tippy-content="open a new window" title='open a new window' data-agent="<%=agent%>">
|
|
1070
1073
|
<div><i class="fa-solid fa-plus"></i></div>
|
|
1071
1074
|
</button>
|
|
@@ -428,6 +428,9 @@ table h3 {
|
|
|
428
428
|
<button class='btn2' id='genlog'><div><i class="fa-solid fa-laptop-code"></i></div><div>Logs</div></button>
|
|
429
429
|
<a id='downloadlogs' download class='hidden btn2' href="/pinokio/logs.zip"><div><i class="fa-solid fa-download"></i></div><div>Download logs</div></a>
|
|
430
430
|
<a class='btn2' href="/home?mode=settings"><div><i class="fa-solid fa-gear"></i></div><div>Settings</div></a>
|
|
431
|
+
<button class='btn2' id='minimize-header' data-tippy-content="minimize header" title='minimize header'>
|
|
432
|
+
<div><i class="fa-solid fa-expand"></i></div>
|
|
433
|
+
</button>
|
|
431
434
|
<button id='new-window' title='open a new window' class='btn2' data-agent="<%=agent%>"><div><i class="fa-solid fa-plus"></i></div><div>Window</div></button>
|
|
432
435
|
</div>
|
|
433
436
|
</h1>
|
|
@@ -414,6 +414,9 @@ input:checked + .slider:before {
|
|
|
414
414
|
<button class='btn2' id='genlog'><div><i class="fa-solid fa-laptop-code"></i></div><div>Logs</div></button>
|
|
415
415
|
<a id='downloadlogs' download class='hidden btn2' href="/pinokio/logs.zip"><div><i class="fa-solid fa-download"></i></div><div>Download logs</div></a>
|
|
416
416
|
<a class='btn2' href="/home?mode=settings"><div><i class="fa-solid fa-gear"></i></div><div>Settings</div></a>
|
|
417
|
+
<button class='btn2' id='minimize-header' data-tippy-content="minimize header" title='minimize header'>
|
|
418
|
+
<div><i class="fa-solid fa-expand"></i></div>
|
|
419
|
+
</button>
|
|
417
420
|
<button id='new-window' title='open a new window' class='btn2' data-agent="<%=agent%>"><div><i class="fa-solid fa-plus"></i></div><div>Window</div></button>
|
|
418
421
|
</div>
|
|
419
422
|
</h1>
|
|
@@ -1014,6 +1014,9 @@ body.dark .appcanvas {
|
|
|
1014
1014
|
<a class='btn2' href="/rows" data-tippy-content="split into 2 rows">
|
|
1015
1015
|
<div><i class="fa-solid fa-table-columns fa-rotate-270"></i></div>
|
|
1016
1016
|
</a>
|
|
1017
|
+
<button class='btn2' id='minimize-header' data-tippy-content="minimize header" title='minimize header'>
|
|
1018
|
+
<div><i class="fa-solid fa-expand"></i></div>
|
|
1019
|
+
</button>
|
|
1017
1020
|
<button class='btn2' id='new-window' data-tippy-content="open a new window" title='open a new window' data-agent="<%=agent%>">
|
|
1018
1021
|
<div><i class="fa-solid fa-plus"></i></div>
|
|
1019
1022
|
</button>
|
package/server/views/review.ejs
CHANGED
|
@@ -954,6 +954,9 @@ body.dark .top-menu .btn2.selected {
|
|
|
954
954
|
<a class='btn2' href="/rows" data-tippy-content="split into 2 rows">
|
|
955
955
|
<div><i class="fa-solid fa-table-columns fa-rotate-270"></i></div>
|
|
956
956
|
</a>
|
|
957
|
+
<button class='btn2' id='minimize-header' data-tippy-content="minimize header" title='minimize header'>
|
|
958
|
+
<div><i class="fa-solid fa-expand"></i></div>
|
|
959
|
+
</button>
|
|
957
960
|
<button class='btn2' id='new-window' data-tippy-content="open a new window" title='open a new window' data-agent="<%=agent%>">
|
|
958
961
|
<div><i class="fa-solid fa-plus"></i></div>
|
|
959
962
|
</button>
|
|
@@ -726,6 +726,9 @@ document.addEventListener('DOMContentLoaded', function() {
|
|
|
726
726
|
<a class='btn2' href="/rows" data-tippy-content="split into 2 rows">
|
|
727
727
|
<div><i class="fa-solid fa-table-columns fa-rotate-270"></i></div>
|
|
728
728
|
</a>
|
|
729
|
+
<button class='btn2' id='minimize-header' data-tippy-content="minimize header" title='minimize header'>
|
|
730
|
+
<div><i class="fa-solid fa-expand"></i></div>
|
|
731
|
+
</button>
|
|
729
732
|
<button class='btn2' id='new-window' data-tippy-content="open a new window" title='open a new window' data-agent="<%=agent%>">
|
|
730
733
|
<div><i class="fa-solid fa-plus"></i></div>
|
|
731
734
|
</button>
|
|
@@ -398,6 +398,9 @@ document.addEventListener('DOMContentLoaded', function() {
|
|
|
398
398
|
<a class='btn2' href="/rows" data-tippy-content="split into 2 rows">
|
|
399
399
|
<div><i class="fa-solid fa-table-columns fa-rotate-270"></i></div>
|
|
400
400
|
</a>
|
|
401
|
+
<button class='btn2' id='minimize-header' data-tippy-content="minimize header" title='minimize header'>
|
|
402
|
+
<div><i class="fa-solid fa-expand"></i></div>
|
|
403
|
+
</button>
|
|
401
404
|
<button class='btn2' id='new-window' data-tippy-content="open a new window" title='open a new window' data-agent="<%=agent%>">
|
|
402
405
|
<div><i class="fa-solid fa-plus"></i></div>
|
|
403
406
|
</button>
|
package/server/views/setup.ejs
CHANGED
|
@@ -144,6 +144,9 @@ body {
|
|
|
144
144
|
<a class='btn2' href="/rows" data-tippy-content="split into 2 rows">
|
|
145
145
|
<div><i class="fa-solid fa-table-columns fa-rotate-270"></i></div>
|
|
146
146
|
</a>
|
|
147
|
+
<button class='btn2' id='minimize-header' data-tippy-content="minimize header" title='minimize header'>
|
|
148
|
+
<div><i class="fa-solid fa-expand"></i></div>
|
|
149
|
+
</button>
|
|
147
150
|
<button class='btn2' id='new-window' data-tippy-content="open a new window" title='open a new window' data-agent="<%=agent%>">
|
|
148
151
|
<div><i class="fa-solid fa-plus"></i></div>
|
|
149
152
|
</button>
|
|
@@ -160,6 +160,9 @@ body.dark .card {
|
|
|
160
160
|
<a class='btn2' href="/rows" data-tippy-content="split into 2 rows">
|
|
161
161
|
<div><i class="fa-solid fa-table-columns fa-rotate-270"></i></div>
|
|
162
162
|
</a>
|
|
163
|
+
<button class='btn2' id='minimize-header' data-tippy-content="minimize header" title='minimize header'>
|
|
164
|
+
<div><i class="fa-solid fa-expand"></i></div>
|
|
165
|
+
</button>
|
|
163
166
|
<button class='btn2' id='new-window' data-tippy-content="open a new window" title='open a new window' data-agent="<%=agent%>">
|
|
164
167
|
<div><i class="fa-solid fa-plus"></i></div>
|
|
165
168
|
</button>
|
|
@@ -381,6 +381,9 @@ body.dark .plugin-option:hover {
|
|
|
381
381
|
<a class='btn2' href="/rows" data-tippy-content="split into 2 rows">
|
|
382
382
|
<div><i class="fa-solid fa-table-columns fa-rotate-270"></i></div>
|
|
383
383
|
</a>
|
|
384
|
+
<button class='btn2' id='minimize-header' data-tippy-content="minimize header" title='minimize header'>
|
|
385
|
+
<div><i class="fa-solid fa-expand"></i></div>
|
|
386
|
+
</button>
|
|
384
387
|
<button class='btn2' id='new-window' data-tippy-content="open a new window" title='open a new window' data-agent="<%=agent%>">
|
|
385
388
|
<div><i class="fa-solid fa-plus"></i></div>
|
|
386
389
|
</button>
|
package/server/views/tools.ejs
CHANGED
|
@@ -1116,6 +1116,9 @@ document.addEventListener('DOMContentLoaded', function() {
|
|
|
1116
1116
|
<a class='btn2' href="/rows" data-tippy-content="split into 2 rows">
|
|
1117
1117
|
<div><i class="fa-solid fa-table-columns fa-rotate-270"></i></div>
|
|
1118
1118
|
</a>
|
|
1119
|
+
<button class='btn2' id='minimize-header' data-tippy-content="minimize header" title='minimize header'>
|
|
1120
|
+
<div><i class="fa-solid fa-expand"></i></div>
|
|
1121
|
+
</button>
|
|
1119
1122
|
<button class='btn2' id='new-window' data-tippy-content="open a new window" title='open a new window' data-agent="<%=agent%>">
|
|
1120
1123
|
<div><i class="fa-solid fa-plus"></i></div>
|
|
1121
1124
|
</button>
|