fix(canvas): move offline status to people badge, toolbar minimize to bottom, zoom to bottom-right
- Offline/reconnecting indicator now shows inside the "N online" people badge instead of the shell header (hidden on canvas via CSS override) - Toolbar collapse/minimize button moved from top to bottom of toolbar stack so it sits where the last tool icon was - Zoom controls moved from bottom-left to bottom-right; on mobile they sit above the bottom toolbar to avoid overlap Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
dbe60f2711
commit
ee1a791aea
|
|
@ -16,6 +16,8 @@
|
|||
<script>(function(){var t=localStorage.getItem('canvas-theme');if(!t)t=matchMedia('(prefers-color-scheme:light)').matches?'light':'dark';document.documentElement.setAttribute('data-theme',t);var b=localStorage.getItem('canvas-bg')||'grid';document.documentElement.setAttribute('data-canvas-bg',b)})()</script>
|
||||
<link rel="stylesheet" href="/theme.css?v=1" />
|
||||
<style>
|
||||
/* Hide shell offline indicator on canvas — shown in people badge instead */
|
||||
rstack-offline-indicator { display: none !important; }
|
||||
/* When loaded inside an iframe, hide shell chrome */
|
||||
html.rspace-embedded .rstack-header { display: none !important; }
|
||||
html.rspace-embedded .rstack-tab-row { display: none !important; }
|
||||
|
|
@ -286,7 +288,7 @@
|
|||
display: block;
|
||||
}
|
||||
|
||||
/* Collapse/expand toggle — at top of toolbar */
|
||||
/* Collapse/expand toggle — at bottom of toolbar */
|
||||
#toolbar-collapse {
|
||||
padding: 6px;
|
||||
background: transparent;
|
||||
|
|
@ -298,7 +300,7 @@
|
|||
text-align: center;
|
||||
color: var(--rs-text-muted);
|
||||
cursor: pointer;
|
||||
order: -1; /* always first */
|
||||
order: 999; /* always last */
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
display: flex;
|
||||
|
|
@ -562,11 +564,11 @@
|
|||
50% { opacity: 0.5; }
|
||||
}
|
||||
|
||||
/* ── Corner tools (zoom + feed) — bottom-left ── */
|
||||
/* ── Corner tools (zoom + feed) — bottom-right ── */
|
||||
#canvas-corner-tools {
|
||||
position: fixed;
|
||||
bottom: 16px;
|
||||
left: 12px;
|
||||
right: 16px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
|
|
@ -983,6 +985,30 @@
|
|||
box-shadow: 0 2px 14px rgba(0, 0, 0, 0.18);
|
||||
}
|
||||
|
||||
#people-conn-status {
|
||||
display: none;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
font-size: 11px;
|
||||
padding-left: 6px;
|
||||
border-left: 1px solid var(--rs-border, rgba(255,255,255,0.1));
|
||||
}
|
||||
|
||||
#people-conn-status.visible {
|
||||
display: inline-flex;
|
||||
}
|
||||
|
||||
#people-conn-status .conn-dot {
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
border-radius: 50%;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
#people-conn-status .conn-dot.pulse {
|
||||
animation: pulse 1.2s ease-in-out infinite;
|
||||
}
|
||||
|
||||
#people-dots {
|
||||
display: flex;
|
||||
gap: 3px;
|
||||
|
|
@ -1810,10 +1836,9 @@
|
|||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
/* Corner tools: horizontal on mobile, tucked bottom-right */
|
||||
/* Corner tools: horizontal on mobile, above bottom toolbar */
|
||||
#canvas-corner-tools {
|
||||
bottom: 8px;
|
||||
left: auto;
|
||||
bottom: 60px;
|
||||
right: 8px;
|
||||
flex-direction: row;
|
||||
padding: 4px 6px;
|
||||
|
|
@ -2010,8 +2035,6 @@
|
|||
</div>
|
||||
|
||||
<div id="toolbar">
|
||||
<button id="toolbar-collapse" title="Minimize toolbar"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round"><line x1="6" y1="18" x2="18" y2="18"/></svg></button>
|
||||
|
||||
<!-- 1. Note -->
|
||||
<div class="toolbar-group">
|
||||
<button class="toolbar-group-toggle" title="Note"><span class="tg-icon">📝</span><span class="tg-label">Note</span></button>
|
||||
|
|
@ -2147,6 +2170,7 @@
|
|||
<button id="new-booking" title="Booking">✈️ Booking</button>
|
||||
</div>
|
||||
</div>
|
||||
<button id="toolbar-collapse" title="Minimize toolbar"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round"><line x1="6" y1="18" x2="18" y2="18"/></svg></button>
|
||||
</div>
|
||||
|
||||
<div id="toolbar-panel">
|
||||
|
|
@ -2246,6 +2270,7 @@
|
|||
<div id="people-online-badge">
|
||||
<span class="dots" id="people-dots"></span>
|
||||
<span id="people-badge-text">1 online</span>
|
||||
<span id="people-conn-status"></span>
|
||||
</div>
|
||||
|
||||
<div id="mp-notify">
|
||||
|
|
@ -2998,6 +3023,8 @@
|
|||
document.getElementById("canvas-loading")?.remove();
|
||||
status.className = "offline";
|
||||
statusText.textContent = "Offline (cached)";
|
||||
connState = "offline";
|
||||
renderPeopleBadge();
|
||||
}
|
||||
} catch (e) {
|
||||
console.warn("[Canvas] Offline cache init failed:", e);
|
||||
|
|
@ -3231,6 +3258,8 @@
|
|||
const peopleBadgeText = document.getElementById("people-badge-text");
|
||||
const peopleCount = document.getElementById("people-count");
|
||||
const peopleList = document.getElementById("people-list");
|
||||
const peopleConnStatus = document.getElementById("people-conn-status");
|
||||
let connState = "connecting"; // "connected" | "offline" | "reconnecting" | "connecting"
|
||||
const pingToast = document.getElementById("ping-toast");
|
||||
const pingToastText = document.getElementById("ping-toast-text");
|
||||
const pingToastGo = document.getElementById("ping-toast-go");
|
||||
|
|
@ -3293,6 +3322,17 @@
|
|||
dotCount++;
|
||||
}
|
||||
peopleCount.textContent = totalCount;
|
||||
// Connection status indicator
|
||||
if (connState === "connected") {
|
||||
peopleConnStatus.classList.remove("visible");
|
||||
peopleConnStatus.innerHTML = "";
|
||||
} else {
|
||||
const color = connState === "offline" ? "#f59e0b" : "#3b82f6";
|
||||
const label = connState === "offline" ? "Offline" : "Reconnecting…";
|
||||
const pulse = connState !== "offline" ? " pulse" : "";
|
||||
peopleConnStatus.innerHTML = `<span class="conn-dot${pulse}" style="background:${color}"></span>${label}`;
|
||||
peopleConnStatus.classList.add("visible");
|
||||
}
|
||||
}
|
||||
|
||||
function renderPeoplePanel() {
|
||||
|
|
@ -3445,15 +3485,19 @@
|
|||
sync.addEventListener("connected", () => {
|
||||
status.className = "connected";
|
||||
statusText.textContent = "Connected";
|
||||
connState = "connected";
|
||||
renderPeopleBadge();
|
||||
});
|
||||
|
||||
sync.addEventListener("disconnected", () => {
|
||||
if (navigator.onLine) {
|
||||
status.className = "disconnected";
|
||||
statusText.textContent = "Reconnecting...";
|
||||
connState = "reconnecting";
|
||||
} else {
|
||||
status.className = "offline";
|
||||
statusText.textContent = "Offline (changes saved locally)";
|
||||
connState = "offline";
|
||||
}
|
||||
// Clear online peers on disconnect (they'll re-announce on reconnect)
|
||||
onlinePeers.clear();
|
||||
|
|
@ -6368,6 +6412,8 @@
|
|||
console.log("[Canvas] Browser went online, reconnecting...");
|
||||
status.className = "syncing";
|
||||
statusText.textContent = "Reconnecting...";
|
||||
connState = "reconnecting";
|
||||
renderPeopleBadge();
|
||||
sync.connect(wsUrl);
|
||||
});
|
||||
|
||||
|
|
@ -6375,6 +6421,8 @@
|
|||
console.log("[Canvas] Browser went offline");
|
||||
status.className = "offline";
|
||||
statusText.textContent = "Offline (changes saved locally)";
|
||||
connState = "offline";
|
||||
renderPeopleBadge();
|
||||
});
|
||||
|
||||
// Handle offline-loaded event
|
||||
|
|
|
|||
Loading…
Reference in New Issue