release(v1.6.10): self-host ReDoc, gate sidebar toggle on auth, and enrich release workflow

This commit is contained in:
Ryan
2025-10-28 02:11:54 -04:00
committed by GitHub
parent ab327acc8a
commit b1bd903072
10 changed files with 2066 additions and 138 deletions

View File

@@ -19,13 +19,15 @@ if (isset($_GET['spec'])) {
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>FileRise API Docs</title>
<script defer src="https://cdn.redoc.ly/redoc/latest/bundles/redoc.standalone.js"
integrity="sha384-70P5pmIdaQdVbxvjhrcTDv1uKcKqalZ3OHi7S2J+uzDl0PW8dO6L+pHOpm9EEjGJ"
crossorigin="anonymous"></script>
<script defer src="/js/redoc-init.js"></script>
<!-- Local ReDoc bundle -->
<script defer src="/vendor/redoc/redoc.standalone.js?v=dev"></script>
<!-- Your init (also local) -->
<script defer src="/js/redoc-init.js?v=dev"></script>
</head>
<body>
<redoc spec-url="api.php?spec=1"></redoc>
<redoc spec-url="/api.php?spec=1"></redoc>
<div id="redoc-container"></div>
</body>
</html>

View File

@@ -490,10 +490,17 @@ function mountHeaderToggle(btn) {
}
function ensureZonesToggle() {
const isAuthed = document.body.classList.contains('authenticated');
let btn = document.getElementById('sidebarToggleFloating');
const host = getHeaderHost();
if (!host) return;
// If not authenticated, make sure the button is gone and bail.
if (!isAuthed) {
if (btn) btn.remove();
return;
}
// ensure the host is a positioning context
const hostStyle = getComputedStyle(host);
if (hostStyle.position === 'static') {
@@ -502,24 +509,25 @@ function ensureZonesToggle() {
if (!btn) {
btn = document.createElement('button');
btn.id = 'sidebarToggleFloating';
btn.type = 'button'; // not a submit
btn.addEventListener('click', (e) => {
e.preventDefault();
e.stopPropagation(); // don't bubble into the <a href="index.html">
setSidebarCollapsed(!isSidebarCollapsed());
updateSidebarToggleUI(); // refresh icon/title
});
['mousedown','mouseup','pointerdown','pointerup'].forEach(evt =>
btn.addEventListener(evt, (e) => e.stopPropagation())
);
btn.type = 'button';
btn.setAttribute('aria-label', 'Toggle panels');
// Prevent accidental navigations / bubbling
btn.addEventListener('click', (e) => {
e.preventDefault();
e.stopPropagation();
setSidebarCollapsed(!isSidebarCollapsed());
updateSidebarToggleUI();
});
['mousedown','mouseup','pointerdown','pointerup'].forEach(evt =>
btn.addEventListener(evt, (e) => e.stopPropagation())
);
Object.assign(btn.style, {
position: 'absolute', // <-- key change (was fixed)
top: '8px', // adjust to line up with header content
left: '65px', // place to the right of your logo; tweak as needed
position: 'absolute',
top: '8px',
left: '65px',
zIndex: '1000',
width: '38px',
height: '38px',
@@ -535,7 +543,7 @@ btn.addEventListener('click', (e) => {
lineHeight: '0'
});
// dark-mode polish (optional)
// Dark mode polish
if (document.body.classList.contains('dark-mode')) {
btn.style.background = '#2c2c2c';
btn.style.border = '1px solid #555';
@@ -543,17 +551,14 @@ btn.addEventListener('click', (e) => {
btn.style.color = '#e0e0e0';
}
btn.addEventListener('click', () => {
setZonesCollapsed(!isZonesCollapsed());
});
// Insert right after the logo if present, else just append to host
// Insert right after the logo if present, else append to host
const afterLogo = host.querySelector('.header-logo');
if (afterLogo && afterLogo.parentNode) {
afterLogo.parentNode.insertBefore(btn, afterLogo.nextSibling);
} else {
host.appendChild(btn);
}
themeToggleButton(btn);
}

View File

@@ -204,8 +204,11 @@ export function triggerLogout() {
credentials: "include",
headers: { "X-CSRF-Token": getCsrfToken() }
})
.then(() => window.location.reload(true))
.catch(() => { });
.then(() => {
document.body.classList.remove('authenticated');
window.location.reload(true);
})
.catch(() => {});
}
// Expose functions for inline handlers.
@@ -239,9 +242,12 @@ document.addEventListener("DOMContentLoaded", function () {
// 3) If authenticated, start app
checkAuthentication().then(authenticated => {
if (authenticated) {
document.body.classList.add('authenticated');
const overlay = document.getElementById('loadingOverlay');
if (overlay) overlay.remove();
initializeApp();
} else {
document.body.classList.remove('authenticated');
}
});

21
public/vendor/redoc/LICENSE vendored Normal file
View File

@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2015-present, Rebilly, Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

1832
public/vendor/redoc/redoc.standalone.js vendored Normal file

File diff suppressed because one or more lines are too long