-
-
-
-
+
+
+
+
+
+
+
+
Click Start session to create a temporary room and generate an invite link.
Live rooms are relayed in memory. Everyone with the live link can edit while the room is active.
diff --git a/script.js b/script.js
index 929646b4..ce124838 100644
--- a/script.js
+++ b/script.js
@@ -11912,6 +11912,10 @@ document.addEventListener("DOMContentLoaded", async function () {
const liveShareStatus = document.getElementById('live-share-status');
const liveShareStatusText = document.getElementById('live-share-status-text');
const liveShareParticipants = document.getElementById('live-share-participants');
+ const liveShareActiveBadge = document.getElementById('live-share-active-badge');
+ const liveShareInviteSection = document.getElementById('live-share-invite-section');
+ const liveShareInviteState = document.getElementById('live-share-invite-state');
+ const liveShareInviteHelp = document.getElementById('live-share-invite-help');
const liveShareToolbarParticipants = document.getElementById('live-share-toolbar-participants');
const liveShareExpiredModal = document.getElementById('live-share-expired-modal');
const liveShareExpiredMessage = document.getElementById('live-share-expired-message');
@@ -12519,6 +12523,30 @@ document.addEventListener("DOMContentLoaded", async function () {
container.appendChild(fragment);
}
+ function updateLiveShareGuidance(isActive, participantCount) {
+ const hasCollaborators = isActive && participantCount > 1;
+ const state = !isActive ? 'idle' : (hasCollaborators ? 'joined' : 'active');
+
+ if (liveShareActiveBadge) {
+ liveShareActiveBadge.hidden = !isActive;
+ liveShareActiveBadge.dataset.state = state;
+ }
+ if (liveShareInviteSection) {
+ liveShareInviteSection.dataset.state = state;
+ }
+ if (liveShareInviteState) {
+ liveShareInviteState.textContent = isActive ? 'Ready to copy' : 'Created after session starts';
+ }
+ if (liveShareInviteHelp) {
+ liveShareInviteHelp.textContent = isActive
+ ? 'Copy this link and send it to collaborators. New participants appear above when they join.'
+ : 'Click Start session to create a temporary room and generate an invite link.';
+ }
+ if (liveShareCopyBtn) {
+ liveShareCopyBtn.title = isActive ? 'Copy invite link' : 'Start a session first';
+ }
+ }
+
function renderLiveParticipants() {
const participants = getLiveParticipants();
const participantCount = participants.length || 1;
@@ -12540,6 +12568,7 @@ document.addEventListener("DOMContentLoaded", async function () {
showLiveParticipantsPopover(event.currentTarget, allParticipants);
}
});
+ updateLiveShareGuidance(true, participantCount);
setLiveShareStatus(status, state);
}
@@ -12556,6 +12585,8 @@ document.addEventListener("DOMContentLoaded", async function () {
liveShareEndBtn.disabled = !isActive;
liveShareEndBtn.hidden = !isActive;
liveShareEndBtn.textContent = isHost ? 'End session' : 'Leave session';
+ liveShareEndBtn.classList.toggle('reset-modal-confirm', isHost);
+ liveShareEndBtn.classList.toggle('reset-modal-cancel', !isHost);
}
if (liveShareCopyBtn) {
liveShareCopyBtn.disabled = !isActive || !liveShareUrlInput || !liveShareUrlInput.value;
@@ -12568,6 +12599,7 @@ document.addEventListener("DOMContentLoaded", async function () {
liveShareToolbarParticipants.hidden = true;
}
if (liveShareUrlInput) liveShareUrlInput.value = '';
+ updateLiveShareGuidance(false, 0);
} else {
renderLiveParticipants();
}
diff --git a/styles.css b/styles.css
index 14f3825d..f61a5916 100644
--- a/styles.css
+++ b/styles.css
@@ -3347,6 +3347,56 @@ a:focus {
background: var(--color-danger-fg);
}
+.live-share-title-row {
+ display: flex;
+ align-items: center;
+ gap: 10px;
+ min-width: 0;
+ flex: 1;
+}
+
+.modal-header .live-share-title-row .reset-modal-message {
+ flex: 0 0 auto;
+}
+
+.live-share-active-badge {
+ display: inline-flex;
+ align-items: center;
+ gap: 7px;
+ width: fit-content;
+ padding: 4px 9px;
+ border: 1px solid rgba(26, 127, 55, 0.28);
+ border-radius: 999px;
+ background: var(--editor-bg);
+ color: #1a7f37;
+ font-size: 12px;
+ font-weight: 700;
+ white-space: nowrap;
+}
+
+.live-share-active-badge[hidden] {
+ display: none;
+}
+
+.live-share-active-dot {
+ width: 8px;
+ height: 8px;
+ border-radius: 50%;
+ background: #1a7f37;
+ box-shadow: 0 0 0 4px rgba(26, 127, 55, 0.12);
+}
+
+.live-share-section-title {
+ font-size: 12px;
+ font-weight: 700;
+ color: var(--text-secondary);
+}
+
+.live-share-participant-panel {
+ display: grid;
+ gap: 7px;
+}
+
.live-share-participants {
display: flex;
flex-wrap: nowrap;
@@ -3467,6 +3517,55 @@ button.live-share-participant-overflow {
background: var(--button-hover);
}
+.live-share-invite {
+ display: grid;
+ gap: 8px;
+ padding: 10px;
+ border: 1px solid var(--border-color);
+ border-radius: 8px;
+ background: var(--editor-bg);
+}
+
+.live-share-invite[data-state="active"],
+.live-share-invite[data-state="joined"] {
+ border-color: rgba(3, 102, 214, 0.45);
+ background: rgba(3, 102, 214, 0.05);
+}
+
+.live-share-invite-header {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ gap: 10px;
+}
+
+.live-share-invite-state {
+ color: var(--text-secondary);
+ font-size: 11px;
+ font-weight: 600;
+ white-space: nowrap;
+}
+
+.live-share-invite[data-state="active"] .live-share-invite-state,
+.live-share-invite[data-state="joined"] .live-share-invite-state {
+ color: var(--accent-color);
+}
+
+.live-share-copy-btn {
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ gap: 6px;
+ min-width: 74px;
+}
+
+.live-share-invite-help {
+ margin: 0;
+ color: var(--text-secondary);
+ font-size: 12px;
+ line-height: 1.35;
+}
+
.live-share-participant-popover {
position: fixed;
z-index: 3500;
@@ -3513,6 +3612,14 @@ button.live-share-participant-overflow {
align-items: stretch;
}
+@media (max-width: 560px) {
+ .live-share-invite-header {
+ align-items: flex-start;
+ flex-direction: column;
+ gap: 3px;
+ }
+}
+
/* ==========================================================================
Multilingual & CJK Optimization styles added by Aegis SEO agency
========================================================================== */