Fix titlebar pear-ctrl overlap; route status into job tray
CI / test (push) Successful in 9m53s

Reserve space for window controls and split the titlebar clusters so brand and chrome no longer collide. Replace the full-screen status spinner with lightweight activity jobs in the event tray.
This commit is contained in:
2026-07-10 21:48:11 -04:00
parent 25ba70cce8
commit 2cccb8a04e
7 changed files with 348 additions and 146 deletions
+38 -41
View File
@@ -46,64 +46,62 @@ export function closeAllModals() {
}
/**
* Show status indicator overlay
* Activity / progress indicator — routes to the job/event tray (no full-screen spinner).
* Falls back to a non-blocking notification if the ops shell is not ready yet.
* @param {string} message - Message to display
*/
export function showStatusIndicator(message = 'Processing...') {
// Check if indicator already exists, if so just update the message
let statusIndicator = document.getElementById('status-indicator');
if (statusIndicator) {
updateStatusIndicator(message);
// Defensive: never leave a legacy full-screen overlay around
removeLegacyStatusOverlay();
if (typeof window !== 'undefined' && window.peardockOps?.showActivity) {
window.peardockOps.showActivity(message);
return;
}
// Create new indicator if it doesn't exist
statusIndicator = document.createElement('div');
statusIndicator.id = 'status-indicator';
statusIndicator.className = 'position-fixed top-0 start-0 w-100 h-100 d-flex justify-content-center align-items-center bg-dark bg-opacity-75';
statusIndicator.innerHTML = `
<div class="text-center">
<div class="spinner-border text-light" role="status">
<span class="visually-hidden">Loading...</span>
</div>
<p class="mt-3 text-light">${message}</p>
</div>
`;
document.body.appendChild(statusIndicator);
try {
notificationManager.add('info', message, { autoDismiss: false, key: 'status-activity' });
} catch {
// ignore
}
}
/**
* Update status indicator message
* Update status / activity message in the job tray
* @param {string} message - New message to display
*/
export function updateStatusIndicator(message) {
const statusIndicator = document.getElementById('status-indicator');
if (statusIndicator) {
const messageElement = statusIndicator.querySelector('p');
if (messageElement) {
messageElement.textContent = message;
}
if (typeof window !== 'undefined' && window.peardockOps?.updateActivity) {
window.peardockOps.updateActivity(message);
return;
}
try {
notificationManager.add('info', message, { autoDismiss: false, key: 'status-activity' });
} catch {
// ignore
}
}
/**
* Hide status indicator overlay
* Safe to call before DOM is ready
* Complete / hide activity indicator in the job tray
* @param {boolean} [ok=true] - Whether the activity succeeded
*/
export function hideStatusIndicator() {
// Use requestAnimationFrame to ensure DOM is ready, or check immediately if already loaded
export function hideStatusIndicator(ok = true) {
if (typeof window !== 'undefined' && window.peardockOps?.completeActivity) {
window.peardockOps.completeActivity(ok !== false);
}
removeLegacyStatusOverlay();
}
function removeLegacyStatusOverlay() {
const remove = () => {
document.getElementById('status-indicator')?.remove();
};
if (typeof document === 'undefined') return;
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', () => {
const statusIndicator = document.getElementById('status-indicator');
if (statusIndicator) {
statusIndicator.remove();
}
});
document.addEventListener('DOMContentLoaded', remove, { once: true });
} else {
const statusIndicator = document.getElementById('status-indicator');
if (statusIndicator) {
statusIndicator.remove();
}
remove();
}
}
@@ -117,4 +115,3 @@ export function showAlert(type, message, options = {}) {
// Use the new notification system
notificationManager.add(type, message, options);
}