@a83/orbiter-admin 0.3.40 → 0.3.41
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 +1 -1
- package/public/style.css +67 -11
- package/public/xfce.js +140 -32
package/package.json
CHANGED
package/public/style.css
CHANGED
|
@@ -2028,23 +2028,47 @@ a.xfce-sb-logo:hover { opacity: .8; }
|
|
|
2028
2028
|
}
|
|
2029
2029
|
.xfce-dock-item { position: relative; }
|
|
2030
2030
|
|
|
2031
|
-
/* Hover
|
|
2032
|
-
.xfce-col-
|
|
2031
|
+
/* Hover preview card above collection dock items */
|
|
2032
|
+
.xfce-col-preview {
|
|
2033
2033
|
position: fixed; z-index: 99990;
|
|
2034
|
-
width: 22px; height: 22px; border-radius: 50%;
|
|
2035
|
-
background: var(--accent);
|
|
2036
|
-
color: color-mix(in srgb, var(--bg1) 15%, #000);
|
|
2037
|
-
font-size: 17px; line-height: 22px; font-weight: 300;
|
|
2038
|
-
text-align: center; text-decoration: none;
|
|
2039
2034
|
transform: translateX(-50%) translateY(6px);
|
|
2040
2035
|
opacity: 0; pointer-events: none;
|
|
2041
|
-
transition: opacity .
|
|
2042
|
-
|
|
2043
|
-
|
|
2036
|
+
transition: opacity .15s, transform .15s cubic-bezier(.34,1.4,.64,1);
|
|
2037
|
+
background: var(--bg1); border: 1px solid var(--line);
|
|
2038
|
+
border-top: 2px solid var(--accent);
|
|
2039
|
+
border-radius: 10px; min-width: 180px; max-width: 240px;
|
|
2040
|
+
box-shadow: 0 4px 24px rgba(0,0,0,.25);
|
|
2041
|
+
overflow: hidden; font-family: var(--mono);
|
|
2044
2042
|
}
|
|
2045
|
-
.xfce-col-
|
|
2043
|
+
.xfce-col-preview.visible {
|
|
2046
2044
|
opacity: 1; transform: translateX(-50%) translateY(0); pointer-events: auto;
|
|
2047
2045
|
}
|
|
2046
|
+
html[data-dock-pos="left"] .xfce-col-preview {
|
|
2047
|
+
transform: translateX(0) translateY(-50%);
|
|
2048
|
+
}
|
|
2049
|
+
html[data-dock-pos="left"] .xfce-col-preview.visible {
|
|
2050
|
+
transform: translateX(6px) translateY(-50%);
|
|
2051
|
+
}
|
|
2052
|
+
.xfce-preview-head { padding: 7px 12px; border-bottom: 1px solid var(--line); }
|
|
2053
|
+
.xfce-preview-head a { font-size: 10px; font-weight: 600; color: var(--accent); text-decoration: none; text-transform: uppercase; letter-spacing: .06em; }
|
|
2054
|
+
.xfce-preview-head a:hover { text-decoration: underline; }
|
|
2055
|
+
.xfce-preview-entries { padding: 4px 0; }
|
|
2056
|
+
.xfce-preview-row {
|
|
2057
|
+
display: flex; align-items: center; justify-content: space-between;
|
|
2058
|
+
padding: 4px 12px; gap: 8px; text-decoration: none;
|
|
2059
|
+
transition: background .1s;
|
|
2060
|
+
}
|
|
2061
|
+
.xfce-preview-row:hover { background: color-mix(in srgb, var(--accent) 10%, transparent); }
|
|
2062
|
+
.xfce-preview-slug { font-size: 10px; color: var(--body); flex: 1; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
|
2063
|
+
.xfce-preview-date { font-size: 9px; color: var(--muted); flex-shrink: 0; }
|
|
2064
|
+
.xfce-preview-empty { padding: 6px 12px; font-size: 10px; color: var(--muted); }
|
|
2065
|
+
.xfce-preview-loading { padding: 10px 12px; font-size: 10px; color: var(--muted); }
|
|
2066
|
+
.xfce-preview-new {
|
|
2067
|
+
display: block; padding: 6px 12px; font-size: 10px;
|
|
2068
|
+
color: var(--accent); text-decoration: none; border-top: 1px solid var(--line);
|
|
2069
|
+
transition: background .1s;
|
|
2070
|
+
}
|
|
2071
|
+
.xfce-preview-new:hover { background: color-mix(in srgb, var(--accent) 10%, transparent); }
|
|
2048
2072
|
|
|
2049
2073
|
/* ── Command Palette ─────────────────────────────────────── */
|
|
2050
2074
|
.xfce-palette {
|
|
@@ -2123,6 +2147,38 @@ a.xfce-sb-logo:hover { opacity: .8; }
|
|
|
2123
2147
|
|
|
2124
2148
|
/* ── Status bar build indicator ──────────────────────────── */
|
|
2125
2149
|
.xfce-sb-build { font-size: 9px; font-family: var(--mono); color: var(--muted); white-space: nowrap; }
|
|
2150
|
+
.xfce-sb-g-ind { font-size: 10px; font-family: var(--mono); color: var(--accent); font-weight: 600; letter-spacing: .05em; animation: xfce-blink .7s step-end infinite; }
|
|
2151
|
+
@keyframes xfce-blink { 0%,100% { opacity:1; } 50% { opacity:.3; } }
|
|
2152
|
+
|
|
2153
|
+
/* ── Left dock mode ───────────────────────────────────────── */
|
|
2154
|
+
html[data-style="xfce"][data-dock-pos="left"] .main {
|
|
2155
|
+
padding-bottom: 20px !important;
|
|
2156
|
+
padding-left: 100px !important;
|
|
2157
|
+
}
|
|
2158
|
+
html[data-style="xfce"][data-dock-pos="left"] .xfce-dock {
|
|
2159
|
+
bottom: auto; left: 16px; top: 50%;
|
|
2160
|
+
transform: translateY(-50%);
|
|
2161
|
+
padding: 10px 6px;
|
|
2162
|
+
align-items: center;
|
|
2163
|
+
}
|
|
2164
|
+
html[data-style="xfce"][data-dock-pos="left"] .xfce-dock-inner {
|
|
2165
|
+
flex-direction: column; align-items: center; gap: 4px;
|
|
2166
|
+
}
|
|
2167
|
+
html[data-style="xfce"][data-dock-pos="left"] .xfce-dock-group {
|
|
2168
|
+
flex-direction: column; align-items: center; gap: 4px;
|
|
2169
|
+
}
|
|
2170
|
+
html[data-style="xfce"][data-dock-pos="left"] .xfce-dock-sep {
|
|
2171
|
+
width: 28px; height: 1px; margin: 2px 0;
|
|
2172
|
+
}
|
|
2173
|
+
html[data-style="xfce"][data-dock-pos="left"] .xfce-dock-item {
|
|
2174
|
+
transform-origin: left center;
|
|
2175
|
+
}
|
|
2176
|
+
html[data-style="xfce"][data-dock-pos="left"] .xfce-toast-host {
|
|
2177
|
+
bottom: 20px; left: 110px; transform: none;
|
|
2178
|
+
}
|
|
2179
|
+
html[data-style="xfce"][data-dock-pos="left"] .xfce-palette {
|
|
2180
|
+
padding-bottom: 20px; padding-left: 100px; align-items: center;
|
|
2181
|
+
}
|
|
2126
2182
|
|
|
2127
2183
|
/* ── Dock context menu ───────────────────────────────────── */
|
|
2128
2184
|
.xfce-ctx-menu {
|
package/public/xfce.js
CHANGED
|
@@ -63,6 +63,7 @@
|
|
|
63
63
|
'</div>',
|
|
64
64
|
'<div class="xfce-sb-center" id="xfce-sb-title"></div>',
|
|
65
65
|
'<div class="xfce-sb-right">',
|
|
66
|
+
'<span id="xfce-sb-g-ind" class="xfce-sb-g-ind" style="display:none" title="g — type destination key">g_</span>',
|
|
66
67
|
'<button id="xfce-sb-palette-btn" class="xfce-sb-palette-btn" title="Command palette (⌘K)">⌘</button>',
|
|
67
68
|
'<span class="xfce-sb-div">·</span>',
|
|
68
69
|
'<span id="xfce-sb-build" class="xfce-sb-build" title="Last build"></span>',
|
|
@@ -168,6 +169,30 @@
|
|
|
168
169
|
openPalette();
|
|
169
170
|
});
|
|
170
171
|
toolsPopup.appendChild(palBtn);
|
|
172
|
+
|
|
173
|
+
var dockSep2 = document.createElement('div');
|
|
174
|
+
dockSep2.className = 'xfce-tools-sep';
|
|
175
|
+
toolsPopup.appendChild(dockSep2);
|
|
176
|
+
|
|
177
|
+
var dockPosBtn = el('button', 'xfce-tools-item');
|
|
178
|
+
dockPosBtn.id = 'xfce-dock-pos-btn';
|
|
179
|
+
function updateDockPosLabel() {
|
|
180
|
+
var pos = document.documentElement.dataset.dockPos || 'bottom';
|
|
181
|
+
dockPosBtn.innerHTML = '<span class="xfce-tools-icon">' + (pos === 'left' ? '⬌' : '⬍') + '</span>'
|
|
182
|
+
+ '<span>Dock: ' + (pos === 'left' ? 'left' : 'bottom') + '</span>';
|
|
183
|
+
}
|
|
184
|
+
updateDockPosLabel();
|
|
185
|
+
dockPosBtn.addEventListener('click', function (e) {
|
|
186
|
+
e.stopPropagation();
|
|
187
|
+
var cur = document.documentElement.dataset.dockPos || 'bottom';
|
|
188
|
+
var next = cur === 'bottom' ? 'left' : 'bottom';
|
|
189
|
+
localStorage.setItem('orb_dock_pos', next);
|
|
190
|
+
document.documentElement.dataset.dockPos = next;
|
|
191
|
+
updateDockPosLabel();
|
|
192
|
+
toolsPopup.classList.remove('open');
|
|
193
|
+
_previewCache = {};
|
|
194
|
+
});
|
|
195
|
+
toolsPopup.appendChild(dockPosBtn);
|
|
171
196
|
document.body.appendChild(toolsPopup);
|
|
172
197
|
document.addEventListener('click', function () {
|
|
173
198
|
toolsPopup.classList.remove('open');
|
|
@@ -187,32 +212,86 @@
|
|
|
187
212
|
toolsPopup.classList.toggle('open');
|
|
188
213
|
}
|
|
189
214
|
|
|
190
|
-
// ── Hover
|
|
191
|
-
var
|
|
215
|
+
// ── Hover preview card above collection items ────────────────────────
|
|
216
|
+
var _previewEl = null, _previewTimer = null, _previewCache = {};
|
|
192
217
|
|
|
193
|
-
function
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
document.body.appendChild(colCreateEl);
|
|
218
|
+
function buildPreview() {
|
|
219
|
+
_previewEl = el('div', 'xfce-col-preview');
|
|
220
|
+
_previewEl.id = 'xfce-col-preview';
|
|
221
|
+
_previewEl.addEventListener('mouseenter', function () { clearTimeout(_previewTimer); });
|
|
222
|
+
_previewEl.addEventListener('mouseleave', function () { _previewTimer = setTimeout(hideColPreview, 150); });
|
|
223
|
+
document.body.appendChild(_previewEl);
|
|
200
224
|
}
|
|
201
225
|
|
|
202
|
-
function
|
|
203
|
-
if (!
|
|
204
|
-
clearTimeout(
|
|
205
|
-
|
|
206
|
-
var dockTop = dock ? dock.getBoundingClientRect().top : 0;
|
|
207
|
-
var itemRect = itemEl.getBoundingClientRect();
|
|
208
|
-
colCreateEl.href = href;
|
|
209
|
-
colCreateEl.style.left = Math.round(itemRect.left + itemRect.width / 2) + 'px';
|
|
210
|
-
colCreateEl.style.top = Math.round(dockTop - 34) + 'px';
|
|
211
|
-
colCreateEl.classList.add('visible');
|
|
226
|
+
function showColPreview(col, itemEl) {
|
|
227
|
+
if (!_previewEl) buildPreview();
|
|
228
|
+
clearTimeout(_previewTimer);
|
|
229
|
+
_previewTimer = setTimeout(function () { _renderPreview(col, itemEl); }, 280);
|
|
212
230
|
}
|
|
213
231
|
|
|
214
|
-
function
|
|
215
|
-
|
|
232
|
+
function _renderPreview(col, itemEl) {
|
|
233
|
+
var dock = document.getElementById('xfce-dock');
|
|
234
|
+
var isLeft = document.documentElement.dataset.dockPos === 'left';
|
|
235
|
+
var dockR = dock ? dock.getBoundingClientRect() : { top: 0, right: 0 };
|
|
236
|
+
var itemR = itemEl.getBoundingClientRect();
|
|
237
|
+
|
|
238
|
+
function place() {
|
|
239
|
+
if (isLeft) {
|
|
240
|
+
_previewEl.style.left = Math.round(dockR.right + 10) + 'px';
|
|
241
|
+
_previewEl.style.top = Math.round(itemR.top + itemR.height / 2 - _previewEl.offsetHeight / 2) + 'px';
|
|
242
|
+
_previewEl.style.bottom = 'auto';
|
|
243
|
+
} else {
|
|
244
|
+
var cx = Math.round(itemR.left + itemR.width / 2);
|
|
245
|
+
_previewEl.style.left = cx + 'px';
|
|
246
|
+
_previewEl.style.bottom = Math.round(window.innerHeight - dockR.top + 10) + 'px';
|
|
247
|
+
_previewEl.style.top = 'auto';
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
var newHref = '/editor.html?collection=' + encodeURIComponent(col.id);
|
|
252
|
+
var entriesHref = col.singleton
|
|
253
|
+
? newHref + '&singleton=1'
|
|
254
|
+
: '/entries.html?col=' + encodeURIComponent(col.id) + '&label=' + encodeURIComponent(col.label);
|
|
255
|
+
|
|
256
|
+
function render(entries) {
|
|
257
|
+
var rows = entries.length
|
|
258
|
+
? entries.slice(0, 3).map(function (e) {
|
|
259
|
+
var slug = e.slug || e.id || '';
|
|
260
|
+
var date = (e.updated_at || e.created_at || '').substring(5, 10);
|
|
261
|
+
var href = '/editor.html?collection=' + encodeURIComponent(col.id) + '&slug=' + encodeURIComponent(slug);
|
|
262
|
+
return '<a class="xfce-preview-row" href="' + href + '">'
|
|
263
|
+
+ '<span class="xfce-preview-slug">' + escHtml(slug) + '</span>'
|
|
264
|
+
+ '<span class="xfce-preview-date">' + date + '</span>'
|
|
265
|
+
+ '</a>';
|
|
266
|
+
}).join('')
|
|
267
|
+
: '<div class="xfce-preview-empty">no entries yet</div>';
|
|
268
|
+
_previewEl.innerHTML =
|
|
269
|
+
'<div class="xfce-preview-head"><a href="' + entriesHref + '">' + escHtml(col.label) + '</a></div>'
|
|
270
|
+
+ '<div class="xfce-preview-entries">' + rows + '</div>'
|
|
271
|
+
+ '<a class="xfce-preview-new" href="' + newHref + '">+ new entry</a>';
|
|
272
|
+
_previewEl.classList.add('visible');
|
|
273
|
+
place();
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
if (_previewCache[col.id]) {
|
|
277
|
+
render(_previewCache[col.id]);
|
|
278
|
+
return;
|
|
279
|
+
}
|
|
280
|
+
_previewEl.innerHTML = '<div class="xfce-preview-loading">…</div>';
|
|
281
|
+
_previewEl.classList.add('visible');
|
|
282
|
+
place();
|
|
283
|
+
fetch('/api/collections/' + encodeURIComponent(col.id) + '/entries?limit=3', { credentials: 'include' })
|
|
284
|
+
.then(function (r) { return r.ok ? r.json() : null; })
|
|
285
|
+
.then(function (d) {
|
|
286
|
+
var entries = d ? (d.entries || (Array.isArray(d) ? d : [])) : [];
|
|
287
|
+
_previewCache[col.id] = entries;
|
|
288
|
+
if (_previewEl.classList.contains('visible')) render(entries);
|
|
289
|
+
});
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
function hideColPreview() {
|
|
293
|
+
clearTimeout(_previewTimer);
|
|
294
|
+
if (_previewEl) _previewEl.classList.remove('visible');
|
|
216
295
|
}
|
|
217
296
|
|
|
218
297
|
// ── Command Palette ───────────────────────────────────────────────────
|
|
@@ -1000,19 +1079,25 @@
|
|
|
1000
1079
|
if (focusedEl) exitFocusMode();
|
|
1001
1080
|
}, true);
|
|
1002
1081
|
|
|
1082
|
+
// Apply saved dock position
|
|
1083
|
+
var _savedDockPos = localStorage.getItem('orb_dock_pos') || 'bottom';
|
|
1084
|
+
document.documentElement.dataset.dockPos = _savedDockPos;
|
|
1085
|
+
|
|
1003
1086
|
// ── Magnification ─────────────────────────────────────────────────
|
|
1004
|
-
function applyMag(cx) {
|
|
1005
|
-
var
|
|
1087
|
+
function applyMag(cx, cy) {
|
|
1088
|
+
var isLeft = document.documentElement.dataset.dockPos === 'left';
|
|
1089
|
+
var items = dockInner.querySelectorAll('.xfce-dock-item');
|
|
1006
1090
|
items.forEach(function (item) {
|
|
1007
1091
|
var r = item.getBoundingClientRect();
|
|
1008
|
-
var mid = r.left + r.width / 2;
|
|
1009
|
-
var
|
|
1092
|
+
var mid = isLeft ? (r.top + r.height / 2) : (r.left + r.width / 2);
|
|
1093
|
+
var pos = isLeft ? cy : cx;
|
|
1094
|
+
var d = Math.abs(pos - mid);
|
|
1010
1095
|
var s = d < 80 ? 1 + (1 - d / 80) * 0.50 : 1;
|
|
1011
1096
|
item.style.setProperty('--ds', s.toFixed(3));
|
|
1012
1097
|
});
|
|
1013
1098
|
}
|
|
1014
1099
|
|
|
1015
|
-
dock.addEventListener('mousemove', function (e) { applyMag(e.clientX); });
|
|
1100
|
+
dock.addEventListener('mousemove', function (e) { applyMag(e.clientX, e.clientY); });
|
|
1016
1101
|
dock.addEventListener('mouseleave', function () {
|
|
1017
1102
|
dockInner.querySelectorAll('.xfce-dock-item').forEach(function (item) {
|
|
1018
1103
|
item.style.setProperty('--ds', '1');
|
|
@@ -1056,12 +1141,9 @@
|
|
|
1056
1141
|
item.appendChild(badge);
|
|
1057
1142
|
}
|
|
1058
1143
|
|
|
1059
|
-
// Hover shows
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
: '/editor.html?collection=' + encodeURIComponent(col.id);
|
|
1063
|
-
item.addEventListener('mouseenter', function () { showColCreate(createHref, item); });
|
|
1064
|
-
item.addEventListener('mouseleave', function () { colCreateTimer = setTimeout(hideColCreate, 120); });
|
|
1144
|
+
// Hover shows preview card with recent entries
|
|
1145
|
+
item.addEventListener('mouseenter', function () { showColPreview(col, item); });
|
|
1146
|
+
item.addEventListener('mouseleave', function () { _previewTimer = setTimeout(hideColPreview, 150); });
|
|
1065
1147
|
|
|
1066
1148
|
// Right-click context menu
|
|
1067
1149
|
addDockCtxMenu(item, col);
|
|
@@ -1124,6 +1206,17 @@
|
|
|
1124
1206
|
}
|
|
1125
1207
|
|
|
1126
1208
|
// ── Keyboard shortcuts ────────────────────────────────────────────────
|
|
1209
|
+
var _gPending = false, _gTimer = null;
|
|
1210
|
+
var G_MAP = { d: '/dashboard.html', m: '/media.html', s: '/settings.html',
|
|
1211
|
+
u: '/users.html', b: '/build.html', i: '/import.html',
|
|
1212
|
+
h: '/schema.html', a: '/account.html' };
|
|
1213
|
+
|
|
1214
|
+
function setGMode(on) {
|
|
1215
|
+
_gPending = on;
|
|
1216
|
+
var ind = document.getElementById('xfce-sb-g-ind');
|
|
1217
|
+
if (ind) ind.style.display = on ? '' : 'none';
|
|
1218
|
+
}
|
|
1219
|
+
|
|
1127
1220
|
function bindKeys() {
|
|
1128
1221
|
// Capture-phase ⌘K: fires before admin-utils.js bubble-phase listener, stops it
|
|
1129
1222
|
document.addEventListener('keydown', function (e) {
|
|
@@ -1146,11 +1239,26 @@
|
|
|
1146
1239
|
// / — open palette (when not typing in an input; Shift+7 on DE keyboard also produces '/')
|
|
1147
1240
|
if (!mod && !e.altKey && e.key === '/' && !isEditing(e.target)) {
|
|
1148
1241
|
e.preventDefault();
|
|
1242
|
+
setGMode(false); clearTimeout(_gTimer);
|
|
1149
1243
|
if (palette && palette.classList.contains('open')) closePalette();
|
|
1150
1244
|
else openPalette();
|
|
1151
1245
|
return;
|
|
1152
1246
|
}
|
|
1153
1247
|
|
|
1248
|
+
// g — vim-style navigation prefix (g d = dashboard, g m = media, …)
|
|
1249
|
+
if (!mod && !e.shiftKey && !e.altKey && e.key === 'g' && !isEditing(e.target)) {
|
|
1250
|
+
e.preventDefault();
|
|
1251
|
+
setGMode(true);
|
|
1252
|
+
clearTimeout(_gTimer);
|
|
1253
|
+
_gTimer = setTimeout(function () { setGMode(false); }, 1500);
|
|
1254
|
+
return;
|
|
1255
|
+
}
|
|
1256
|
+
if (_gPending && !isEditing(e.target)) {
|
|
1257
|
+
clearTimeout(_gTimer); setGMode(false);
|
|
1258
|
+
if (G_MAP[e.key]) { e.preventDefault(); location.href = G_MAP[e.key]; }
|
|
1259
|
+
return;
|
|
1260
|
+
}
|
|
1261
|
+
|
|
1154
1262
|
// ⌘⇧D — toggle HUD
|
|
1155
1263
|
if (mod && e.shiftKey && (e.key === 'd' || e.key === 'D')) {
|
|
1156
1264
|
e.preventDefault();
|