mirror of
https://github.com/Shik3i/KoalaSync.git
synced 2026-08-26 02:27:11 +00:00
UX Improvements: Onboarding, UI Feedback, Auto-Copy Invite
This commit is contained in:
+33
-16
@@ -247,7 +247,7 @@
|
||||
<button class="tab-btn active" data-tab="tab-room">Room</button>
|
||||
<button class="tab-btn" data-tab="tab-sync">Sync</button>
|
||||
<button class="tab-btn" data-tab="tab-settings">Settings</button>
|
||||
<button class="tab-btn" data-tab="tab-dev">Dev</button>
|
||||
<button class="tab-btn" data-tab="tab-dev" title="Advanced Diagnostics & Logs">Status</button>
|
||||
</div>
|
||||
|
||||
<!-- Room Tab -->
|
||||
@@ -255,6 +255,10 @@
|
||||
|
||||
<!-- JOIN SECTION: Visible when not in a room -->
|
||||
<div id="section-join">
|
||||
<button id="createRoomBtn" class="primary" style="margin-bottom: 16px; padding: 14px; font-size: 15px; background: linear-gradient(135deg, #6366f1, #a855f7); box-shadow: 0 4px 12px rgba(99, 102, 241, 0.4);">+ Create New Room</button>
|
||||
<details style="margin-bottom: 12px; background: var(--card); border: 1px solid #334155; border-radius: 8px; padding: 8px;">
|
||||
<summary style="font-size: 11px; font-weight: 700; color: var(--text-muted); text-transform: uppercase; cursor: pointer; outline: none;">Manual Connect / Advanced</summary>
|
||||
<div style="margin-top: 12px;">
|
||||
<div class="form-group">
|
||||
<label>Server</label>
|
||||
<div style="display:flex; gap:4px; margin-bottom:8px;">
|
||||
@@ -273,7 +277,6 @@
|
||||
</div>
|
||||
<div id="roomError" style="display:none; color:var(--error); font-size:11px; margin-bottom:8px; text-align:center;"></div>
|
||||
<button id="joinBtn" class="primary">Join Room</button>
|
||||
<button id="createRoomBtn" class="secondary" style="border: 1px solid var(--accent); color: var(--accent);">Create Random Room</button>
|
||||
|
||||
<div style="display: flex; justify-content: space-between; align-items: center; margin-top: 1.5rem; margin-bottom: 8px;">
|
||||
<label style="margin:0;">Public Rooms</label>
|
||||
@@ -282,6 +285,8 @@
|
||||
<div id="publicRooms" class="info-card" style="max-height: 120px; overflow-y: auto; padding: 4px;">
|
||||
<div style="text-align:center; color: var(--text-muted); font-size: 11px; padding: 10px;">Refreshing...</div>
|
||||
</div>
|
||||
</div>
|
||||
</details>
|
||||
</div>
|
||||
|
||||
<!-- ACTIVE SECTION: Visible when in a room -->
|
||||
@@ -315,8 +320,10 @@
|
||||
|
||||
<!-- Sync Tab -->
|
||||
<div id="tab-sync" class="tab-content">
|
||||
<!-- SYNC ACTIVE: Visible when in a room -->
|
||||
<div id="sync-active">
|
||||
<div class="form-group">
|
||||
<label>Target Tab (Video Source)</label>
|
||||
<label>Select Video</label>
|
||||
<select id="targetTab">
|
||||
<option value="">-- Select a Tab --</option>
|
||||
</select>
|
||||
@@ -329,7 +336,7 @@
|
||||
</div>
|
||||
|
||||
<div style="display: flex; gap: 8px; margin-bottom: 15px; align-items: stretch;">
|
||||
<button id="forceSyncBtn" class="primary" style="background: linear-gradient(135deg, #6366f1, #a855f7); flex: 1;">⚡ Force Sync</button>
|
||||
<button id="forceSyncBtn" class="primary" style="background: linear-gradient(135deg, #6366f1, #a855f7); flex: 1;">⚡ Sync All Viewers</button>
|
||||
<select id="forceSyncMode" style="width: auto; min-width: 130px; background: var(--card); border: 1px solid #334155; color: white; padding: 10px 8px; border-radius: 8px; font-size: 11px; font-family: inherit; cursor: pointer; align-self: stretch;" title="Choose sync target">
|
||||
<option value="jump-to-others">Jump to Others</option>
|
||||
<option value="jump-to-me">Jump to Me</option>
|
||||
@@ -353,35 +360,45 @@
|
||||
</div>
|
||||
|
||||
<div id="peerListSync" class="info-card" style="display:none;"></div>
|
||||
</div>
|
||||
|
||||
<!-- SYNC INACTIVE: Visible when not in a room -->
|
||||
<div id="sync-inactive" style="display:none; text-align: center; padding: 20px 10px;">
|
||||
<div style="font-size: 32px; margin-bottom: 12px;">🔒</div>
|
||||
<h3 style="margin: 0 0 8px 0; color: var(--accent); font-size: 15px;">Connect to a room first</h3>
|
||||
<p style="color: var(--text-muted); font-size: 12px; margin-bottom: 20px;">You need to join a room via an invite link or create a new one to sync videos.</p>
|
||||
<button id="syncTabCreateRoomBtn" class="primary" style="padding: 12px; font-size: 14px; background: linear-gradient(135deg, #6366f1, #a855f7); box-shadow: 0 4px 12px rgba(99, 102, 241, 0.4);">Create New Room</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Settings Tab -->
|
||||
<div id="tab-settings" class="tab-content">
|
||||
<div class="form-group">
|
||||
<label>Your Username</label>
|
||||
<input type="text" id="username" placeholder="Anonymous Koala" maxlength="20">
|
||||
<div class="form-group" style="display: flex; align-items: center; justify-content: space-between; background: var(--card); padding: 10px; border-radius: 8px; margin-bottom: 12px; border: 1px solid #334155;">
|
||||
<label style="margin-bottom: 0;" title="Username helps others identify you.">Your Username ℹ️</label>
|
||||
<input type="text" id="username" placeholder="Anonymous Koala" maxlength="20" style="width: 150px;">
|
||||
</div>
|
||||
|
||||
<div class="form-group" style="display: flex; align-items: center; justify-content: space-between; background: var(--card); padding: 10px; border-radius: 8px; margin-bottom: 12px; border: 1px solid #334155;">
|
||||
<label style="margin-bottom: 0;">Filter Noise Tabs</label>
|
||||
<label style="margin-bottom: 0;" title="Hides non-video sites like search engines or social media.">Hide Clutter Tabs ℹ️</label>
|
||||
<input type="checkbox" id="filterNoise" style="width: auto;" checked>
|
||||
</div>
|
||||
|
||||
<div class="form-group" style="display: flex; align-items: center; justify-content: space-between; background: var(--card); padding: 10px; border-radius: 8px; margin-bottom: 12px; border: 1px solid #334155;">
|
||||
<label style="margin-bottom: 0;">Auto-Sync Next Episode</label>
|
||||
<label style="margin-bottom: 0;" title="Pauses automatically and waits for all peers when an episode changes, then sync-starts together.">Auto-Sync Next Episode ℹ️</label>
|
||||
<input type="checkbox" id="autoSyncNextEpisode" style="width: auto;">
|
||||
</div>
|
||||
|
||||
<div class="form-group" style="display: flex; align-items: center; justify-content: space-between; background: var(--card); padding: 10px; border-radius: 8px; margin-bottom: 12px; border: 1px solid #334155;">
|
||||
<label style="margin-bottom: 0;" title="Automatically copies the invite link to your clipboard when creating a new room.">Auto-Copy Invite Link ℹ️</label>
|
||||
<input type="checkbox" id="autoCopyInvite" style="width: auto;" checked>
|
||||
</div>
|
||||
|
||||
<div class="form-group" style="display: flex; align-items: center; justify-content: space-between; background: var(--card); padding: 10px; border-radius: 8px; margin-bottom: 12px; border: 1px solid #334155;">
|
||||
<label style="margin-bottom: 0;">Browser Notifications</label>
|
||||
<input type="checkbox" id="browserNotifications" style="width: auto;">
|
||||
</div>
|
||||
|
||||
<div style="font-size: 11px; color: var(--text-muted); padding: 8px;">
|
||||
<p>• Username helps others identify you.</p>
|
||||
<p>• Noise filtering uses a blacklist to hide common non-video sites (e.g. Search, Social Media) from the Target Tab selector.</p>
|
||||
<p>• Auto-Sync will pause and wait for all peers when an episode changes, then sync-start together.</p>
|
||||
</div>
|
||||
|
||||
|
||||
<div style="margin-top: 15px; padding: 8px; border-top: 1px solid var(--card);">
|
||||
<label>Troubleshooting</label>
|
||||
@@ -427,8 +444,8 @@
|
||||
<script src="popup.js" type="module"></script>
|
||||
|
||||
<!-- Onboarding Overlay -->
|
||||
<div id="onboarding-overlay" style="display:none; position:fixed; inset:0; background:rgba(0,0,0,0.7); z-index:1000; align-items:center; justify-content:center;">
|
||||
<div id="onboarding-card" style="background:var(--card); padding:24px; border-radius:16px; max-width:280px; width:90%; text-align:center; box-shadow:0 8px 32px rgba(0,0,0,0.5);">
|
||||
<div id="onboarding-overlay" style="display:none; position:fixed; inset:0; background:rgba(0,0,0,0.5); backdrop-filter: blur(2px); z-index:1000; align-items:center; justify-content:center;">
|
||||
<div id="onboarding-card" style="background:var(--card); padding:24px; border-radius:16px; max-width:280px; width:90%; text-align:center; box-shadow:0 8px 32px rgba(0,0,0,0.5); margin-top: 50px;">
|
||||
<div id="onboarding-icon" style="font-size:48px; margin-bottom:12px;">\u{1F44B}</div>
|
||||
<h2 id="onboarding-title" style="color:var(--accent); margin:0 0 8px; font-size:16px;">Welcome to KoalaSync!</h2>
|
||||
<p id="onboarding-text" style="color:var(--text-muted); font-size:13px; margin:0 0 16px; line-height:1.4;">Let's get you started.</p>
|
||||
|
||||
+107
-21
@@ -46,7 +46,8 @@ const elements = {
|
||||
episodeLobbyCard: document.getElementById('episodeLobbyCard'),
|
||||
lobbyTitle: document.getElementById('lobbyTitle'),
|
||||
lobbyPeerStatus: document.getElementById('lobbyPeerStatus'),
|
||||
browserNotifications: document.getElementById('browserNotifications')
|
||||
browserNotifications: document.getElementById('browserNotifications'),
|
||||
autoCopyInvite: document.getElementById('autoCopyInvite')
|
||||
};
|
||||
|
||||
let localPeerId = null;
|
||||
@@ -63,7 +64,7 @@ let forceSyncDone = false;
|
||||
// --- Initialization ---
|
||||
async function init() {
|
||||
// Load Settings
|
||||
const data = await chrome.storage.sync.get(['serverUrl', 'useCustomServer', 'roomId', 'password', 'filterNoise', 'username', 'autoSyncNextEpisode', 'forceSyncMode', 'browserNotifications']);
|
||||
const data = await chrome.storage.sync.get(['serverUrl', 'useCustomServer', 'roomId', 'password', 'filterNoise', 'username', 'autoSyncNextEpisode', 'forceSyncMode', 'browserNotifications', 'autoCopyInvite']);
|
||||
let username = data.username;
|
||||
if (!username) {
|
||||
const adjs = ['Happy', 'Cool', 'Fast', 'Smart', 'Brave', 'Calm', 'Sneaky', 'Lazy', 'Wild', 'Chill', 'Lucky', 'Epic', 'Swift', 'Bold', 'Mighty', 'Cosmic', 'Neon', 'Shadow', 'Crystal', 'Thunder', 'Silent', 'Golden', 'Fierce', 'Noble', 'Mystic', 'Frozen', 'Blazing', 'Sapphire', 'Iron', 'Crimson'];
|
||||
@@ -76,10 +77,11 @@ async function init() {
|
||||
elements.roomId.value = data.roomId || '';
|
||||
elements.password.value = data.password || '';
|
||||
elements.username.value = username;
|
||||
elements.filterNoise.checked = data.filterNoise !== false;
|
||||
elements.autoSyncNextEpisode.checked = data.autoSyncNextEpisode !== false;
|
||||
elements.forceSyncMode.value = data.forceSyncMode || 'jump-to-others';
|
||||
elements.browserNotifications.checked = data.browserNotifications === true;
|
||||
if (elements.filterNoise) elements.filterNoise.checked = data.filterNoise !== false;
|
||||
if (elements.autoSyncNextEpisode) elements.autoSyncNextEpisode.checked = data.autoSyncNextEpisode !== false;
|
||||
if (elements.forceSyncMode) elements.forceSyncMode.value = data.forceSyncMode || 'jump-to-others';
|
||||
if (elements.browserNotifications) elements.browserNotifications.checked = data.browserNotifications === true;
|
||||
if (elements.autoCopyInvite) elements.autoCopyInvite.checked = data.autoCopyInvite !== false;
|
||||
|
||||
// Set Version Info
|
||||
const versionEl = document.getElementById('appVersion');
|
||||
@@ -142,6 +144,11 @@ function toggleUIState(inRoom) {
|
||||
if (elements.sectionJoin) elements.sectionJoin.style.display = inRoom ? 'none' : 'block';
|
||||
if (elements.sectionActive) elements.sectionActive.style.display = inRoom ? 'block' : 'none';
|
||||
if (elements.peerListSync) elements.peerListSync.style.display = inRoom ? 'block' : 'none';
|
||||
|
||||
const syncActive = document.getElementById('sync-active');
|
||||
const syncInactive = document.getElementById('sync-inactive');
|
||||
if (syncActive) syncActive.style.display = inRoom ? 'block' : 'none';
|
||||
if (syncInactive) syncInactive.style.display = inRoom ? 'none' : 'block';
|
||||
}
|
||||
|
||||
function updateUI(roomId, password, useCustomServer = false, serverUrl = '') {
|
||||
@@ -152,6 +159,14 @@ function updateUI(roomId, password, useCustomServer = false, serverUrl = '') {
|
||||
const encodedUrl = encodeURIComponent(serverUrl || '');
|
||||
const invite = `${OFFICIAL_LANDING_PAGE_URL}/join.html#join:${roomId}:${password}:${serverFlag}:${encodedUrl}`;
|
||||
elements.inviteLink.value = invite;
|
||||
|
||||
if (window.justCreatedRoom) {
|
||||
window.justCreatedRoom = false;
|
||||
if (elements.autoCopyInvite && elements.autoCopyInvite.checked && elements.copyInvite) {
|
||||
elements.copyInvite.click();
|
||||
}
|
||||
}
|
||||
|
||||
if (elements.activeRoomId) elements.activeRoomId.textContent = roomId;
|
||||
if (elements.activeServer) {
|
||||
elements.activeServer.textContent = useCustomServer ? (serverUrl || 'Custom Server') : 'Official Server';
|
||||
@@ -597,6 +612,13 @@ async function populateTabs(providedPeers = null, providedTargetTabId = null) {
|
||||
|
||||
if (currentTargetTabId) {
|
||||
elements.targetTab.value = currentTargetTabId;
|
||||
} else {
|
||||
const matchOpt = options.find(o => o.textContent.includes('⭐ MATCH:'));
|
||||
if (matchOpt && elements.targetTab.options.length > 1) {
|
||||
elements.targetTab.value = matchOpt.value;
|
||||
const tabTitle = matchOpt.text.replace('⭐ MATCH: ', '') || null;
|
||||
chrome.runtime.sendMessage({ type: 'SET_TARGET_TAB', tabId: parseInt(matchOpt.value), tabTitle });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -815,6 +837,12 @@ elements.browserNotifications.addEventListener('change', () => {
|
||||
chrome.storage.sync.set({ browserNotifications: elements.browserNotifications.checked });
|
||||
});
|
||||
|
||||
if (elements.autoCopyInvite) {
|
||||
elements.autoCopyInvite.addEventListener('change', () => {
|
||||
chrome.storage.sync.set({ autoCopyInvite: elements.autoCopyInvite.checked });
|
||||
});
|
||||
}
|
||||
|
||||
elements.forceSyncMode.addEventListener('change', () => {
|
||||
chrome.storage.sync.set({ forceSyncMode: elements.forceSyncMode.value });
|
||||
});
|
||||
@@ -931,17 +959,23 @@ elements.leaveBtn.addEventListener('click', async () => {
|
||||
updateUI(null, null);
|
||||
});
|
||||
|
||||
elements.createRoomBtn.addEventListener('click', () => {
|
||||
const animals = ['koala', 'panda', 'tiger', 'eagle', 'fox', 'bear'];
|
||||
const adj = ['happy', 'cool', 'fast', 'smart', 'brave', 'calm'];
|
||||
const id = `${adj[Math.floor(Math.random() * adj.length)]}-${animals[Math.floor(Math.random() * animals.length)]}-${Math.floor(Math.random() * 100)}`;
|
||||
const array = new Uint32Array(1);
|
||||
window.crypto.getRandomValues(array);
|
||||
const pass = array[0].toString(36).substring(0, 6);
|
||||
function handleCreateRoom() {
|
||||
const generateId = () => Math.random().toString(36).substring(2, 8).toUpperCase();
|
||||
const roomId = generateId();
|
||||
const password = generateId();
|
||||
elements.roomId.value = roomId;
|
||||
elements.password.value = password;
|
||||
window.justCreatedRoom = true;
|
||||
|
||||
elements.roomId.value = id;
|
||||
elements.password.value = pass;
|
||||
// Auto-connect
|
||||
elements.joinBtn.click();
|
||||
};
|
||||
|
||||
elements.createRoomBtn.addEventListener('click', handleCreateRoom);
|
||||
const syncTabCreateRoomBtn = document.getElementById('syncTabCreateRoomBtn');
|
||||
if (syncTabCreateRoomBtn) syncTabCreateRoomBtn.addEventListener('click', () => {
|
||||
document.querySelector('.tab-btn[data-tab="tab-room"]').click();
|
||||
handleCreateRoom();
|
||||
});
|
||||
|
||||
elements.refreshRooms.addEventListener('click', () => {
|
||||
@@ -1045,6 +1079,12 @@ elements.forceSyncBtn.addEventListener('click', async () => {
|
||||
});
|
||||
|
||||
elements.playBtn.addEventListener('click', () => {
|
||||
if (!elements.targetTab.value) {
|
||||
showToast('Please select a video first!', 'warning');
|
||||
return;
|
||||
}
|
||||
elements.playBtn.textContent = 'Playing...';
|
||||
elements.playBtn.disabled = true;
|
||||
chrome.runtime.sendMessage({
|
||||
type: 'CONTENT_EVENT',
|
||||
action: EVENTS.PLAY,
|
||||
@@ -1053,6 +1093,12 @@ elements.playBtn.addEventListener('click', () => {
|
||||
});
|
||||
|
||||
elements.pauseBtn.addEventListener('click', () => {
|
||||
if (!elements.targetTab.value) {
|
||||
showToast('Please select a video first!', 'warning');
|
||||
return;
|
||||
}
|
||||
elements.pauseBtn.textContent = 'Pausing...';
|
||||
elements.pauseBtn.disabled = true;
|
||||
chrome.runtime.sendMessage({
|
||||
type: 'CONTENT_EVENT',
|
||||
action: EVENTS.PAUSE,
|
||||
@@ -1122,6 +1168,23 @@ chrome.runtime.onMessage.addListener((msg) => {
|
||||
const action = actionNames[state.action] || state.action;
|
||||
showToast(`${state.senderId} ${action}`, 'info', 2000);
|
||||
}
|
||||
|
||||
if (state && (state.action === 'play' || state.action === 'pause')) {
|
||||
const btn = state.action === 'play' ? elements.playBtn : elements.pauseBtn;
|
||||
if (btn && btn.disabled) {
|
||||
chrome.runtime.sendMessage({ type: 'GET_STATUS' }, (res) => {
|
||||
const peerCount = res && res.peers ? res.peers.length : 1;
|
||||
if (state.acks && state.acks.length >= peerCount) {
|
||||
btn.textContent = '✅ Synced!';
|
||||
setTimeout(() => {
|
||||
btn.disabled = false;
|
||||
btn.textContent = state.action === 'play' ? '▶ Play' : '⏸ Pause';
|
||||
}, 2000);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (state && state.action === 'force_sync_execute') {
|
||||
forceSyncDone = true;
|
||||
if (forceSyncResetTimer) {
|
||||
@@ -1130,7 +1193,10 @@ chrome.runtime.onMessage.addListener((msg) => {
|
||||
}
|
||||
if (elements.forceSyncBtn) {
|
||||
elements.forceSyncBtn.disabled = false;
|
||||
elements.forceSyncBtn.textContent = '⚡ Force Sync';
|
||||
elements.forceSyncBtn.textContent = '✅ Synced!';
|
||||
setTimeout(() => {
|
||||
elements.forceSyncBtn.textContent = '⚡ Sync All Viewers';
|
||||
}, 2000);
|
||||
}
|
||||
}
|
||||
chrome.runtime.sendMessage({ type: 'GET_STATUS' }, (res) => {
|
||||
@@ -1339,11 +1405,11 @@ function updateLobbyUI(lobby, peers) {
|
||||
|
||||
// --- Onboarding Tour ---
|
||||
const onboardingSteps = [
|
||||
{ icon: '\u{1F44B}', title: 'Welcome to KoalaSync!', text: 'Watch videos together in perfect sync — no matter where you are. Let\'s take a quick tour!' },
|
||||
{ icon: '\u{1F3E0}', title: 'Room Tab', text: 'Create a room and share the invite link with friends. Anyone with the link can join instantly.' },
|
||||
{ icon: '\u{1F3AC}', title: 'Sync Tab', text: 'Pick the tab with your video. Play, pause, and seek — everyone stays in sync. Drift? Just hit Force Sync.' },
|
||||
{ icon: '\u2699\uFE0F', title: 'Settings', text: 'Pick a fun username, hide distracting tabs, and enable notifications so you never miss a moment.' },
|
||||
{ icon: '\u{1F389}', title: 'You\'re all set!', text: 'Open a video, create a room, and start watching together. Enjoy!' }
|
||||
{ icon: '👋', title: 'Welcome to KoalaSync!', text: 'Watch videos together in perfect sync — no matter where you are. Let\'s take a quick tour!', targetTab: 'tab-room' },
|
||||
{ icon: '🏠', title: '1. Create a Room', text: 'Start here. Create a room and share the invite link with your friends.', targetTab: 'tab-room' },
|
||||
{ icon: '🎬', title: '2. Select Video', text: 'Navigate here to select the video you want to sync. Play, pause, and seek — everyone stays in sync.', targetTab: 'tab-sync' },
|
||||
{ icon: '⚙️', title: '3. Personalize', text: 'Pick a fun username so your friends know who you are.', targetTab: 'tab-settings' },
|
||||
{ icon: '🎉', title: 'You\'re all set!', text: 'Time to grab some popcorn. Enjoy watching together!', targetTab: 'tab-room' }
|
||||
];
|
||||
|
||||
let onboardingStep = 0;
|
||||
@@ -1368,6 +1434,23 @@ function renderOnboardingStep() {
|
||||
title.textContent = step.title;
|
||||
text.textContent = step.text;
|
||||
|
||||
if (step.targetTab) {
|
||||
const tabBtn = document.querySelector(`.tab-btn[data-tab="${step.targetTab}"]`);
|
||||
if (tabBtn) tabBtn.click();
|
||||
|
||||
const syncActive = document.getElementById('sync-active');
|
||||
const syncInactive = document.getElementById('sync-inactive');
|
||||
if (step.targetTab === 'tab-sync') {
|
||||
if (syncActive) syncActive.style.display = 'block';
|
||||
if (syncInactive) syncInactive.style.display = 'none';
|
||||
} else {
|
||||
// Restore actual lock state when on other tabs so we don't leave it unlocked
|
||||
const inRoom = elements.sectionActive && elements.sectionActive.style.display === 'block';
|
||||
if (syncActive) syncActive.style.display = inRoom ? 'block' : 'none';
|
||||
if (syncInactive) syncInactive.style.display = inRoom ? 'none' : 'block';
|
||||
}
|
||||
}
|
||||
|
||||
dots.replaceChildren();
|
||||
onboardingSteps.forEach((_, i) => {
|
||||
const dot = document.createElement('div');
|
||||
@@ -1382,6 +1465,9 @@ function completeOnboarding() {
|
||||
const overlay = document.getElementById('onboarding-overlay');
|
||||
if (overlay) overlay.style.display = 'none';
|
||||
chrome.storage.sync.set({ onboardingComplete: true });
|
||||
|
||||
const inRoom = elements.sectionActive && elements.sectionActive.style.display === 'block';
|
||||
toggleUIState(inRoom);
|
||||
}
|
||||
|
||||
document.getElementById('onboarding-next')?.addEventListener('click', () => {
|
||||
|
||||
Reference in New Issue
Block a user