diff --git a/html/demo.js b/html/demo.js index 4cf8bb2..1791b7c 100644 --- a/html/demo.js +++ b/html/demo.js @@ -81,7 +81,7 @@ function prettyTime(ms) { function joinBucket(i) { return () => { - window.buckets.children[i].children[0].children[1].disabled = true; + window.buckets.children[i+1].children[0].children[1].disabled = true; audioOffset.value = first_bucket_s + DELAY_INTERVAL * i; audio_offset_change(); } @@ -581,6 +581,7 @@ function persist_checkbox(checkboxId) { persist("userName"); persist_checkbox("disableTutorial"); persist_checkbox("disableLatencyMeasurement"); +persist_checkbox("presentationMode"); // Don't persist "disable auto gain" because it's an experimental feature // Persisting select boxes is harder, so we do it manually for inSelect. @@ -668,7 +669,7 @@ function set_controls() { setVisibleIn(window.advancedSettingsTab, [APP_RUNNING], 'inline-block'); setVisibleIn(window.debugTab, [APP_RUNNING], 'inline-block'); - + setVisibleIn(window.mainApp, allStatesExcept([APP_RUNNING])); setVisibleIn(window.topbar, allStatesExcept([APP_RUNNING])); setVisibleIn(window.tabbarLogo, [APP_RUNNING]); @@ -720,8 +721,21 @@ function set_controls() { window.backingTrackUploader.style.display = "none"; window.backingTrackUploadOk.style.display = "none"; window.backingTrackUploadError.style.display = "none"; + + window.buckets.classList.toggle( + "fullscreen", window.presentationMode.checked); } +window.presentationMode.addEventListener("change", () => { + window.buckets.classList.toggle( + "fullscreen", window.presentationMode.checked); +}); + +window.leavePresentationMode.addEventListener("click", () => { + window.presentationMode.checked = false; + window.buckets.classList.remove("fullscreen"); +}); + function in_select_change() { window.localStorage.setItem("inSelect", inSelect.value); reset_if_running(); @@ -896,6 +910,7 @@ async function enable_video() { myVideoDiv = localVideoTrack.attach(); myVideoDiv.style.transform = 'scale(-1, 1)'; ensureParticipantDiv(myUserid); + removeMockVideo(participantDivs[myUserid]); participantDivs[myUserid].appendChild(myVideoDiv); } @@ -1116,7 +1131,7 @@ function update_active_users( if (userid == myUserid) { for (var j = 0 ; j < N_BUCKETS; j++) { - window.buckets.children[j].children[0].children[1].disabled = + window.buckets.children[j+1].children[0].children[1].disabled = (j == 0 && !backingTrackOn && !imLeading) || est_bucket === j; } } @@ -1427,9 +1442,23 @@ function ensureParticipantDiv(userid) { const info = document.createElement("div"); info.classList.add("participantInfo"); div.appendChild(info); + + /* + const mockVideo = document.createElement("img"); + mockVideo.src = "https://www.jefftk.com/bucket-brigade-logo.png"; + div.appendChild(mockVideo); + */ } } +function removeMockVideo(participantDiv) { + const imgs = participantDiv.getElementsByTagName("img"); + for (let i = 0 ; i < imgs.length; i++) { + participantDiv.removeChild(imgs[i]); + } +} + + async function connect_camera() { switch_app_state(APP_CHOOSE_CAMERA); window.nextCamera.disabled = true; @@ -1509,6 +1538,7 @@ async function selected_camera(useCamera) { localStorage.setItem("camera_device_id", camera_devices[chosen_camera_index].deviceId); ensureParticipantDiv(myUserid); + removeMockVideo(participantDivs[myUserid]); participantDivs[myUserid].appendChild(myVideoDiv); user_bucket_index[myUserid] = 0; bucket_divs[0].appendChild(participantDivs[myUserid]); @@ -1621,6 +1651,7 @@ function connect_twilio() { } ensureParticipantDiv(participant.identity); + removeMockVideo(participantDivs[myUserid]); participant.tracks.forEach( addPublicationOrTrack(participant.identity)); @@ -1854,7 +1885,8 @@ async function start_singing() { } const showBuckets = hasLeader || song_active(); - window.buckets.style.display = showBuckets ? "flex" : "none"; + window.buckets.style.display = showBuckets ? ( + window.presentationMode.checked ? "block" : "flex") : "none"; window.unbucketedUsers.style.display = showBuckets ? "none" : "block"; if (!showBuckets) { diff --git a/html/index.html b/html/index.html index 4ae4ff2..743ed3c 100644 --- a/html/index.html +++ b/html/index.html @@ -216,6 +216,17 @@ flex-wrap: wrap; margin: 0.5em; } +#buckets.fullscreen { + position: fixed; + margin: 0; + top: 0; + left: 0; + background-color: black; + width: 100vw; + height: 100vw; + padding: 0; +} + #unbucketedUsers { flex-grow: 1; text-align: center; @@ -232,6 +243,9 @@ .bucket > * { margin : 0.5em; } +#buckets.fullscreen .bucket > * { + margin : 0; +} .bucketTitle { width: 100%; border-radius: 0.25em 0.25em 0 0; @@ -241,6 +255,23 @@ flex-direction: row; justify-content: space-between; } +#buckets.fullscreen .bucket { + margin: 0; + border: none; + border-radius: 0; + flex-grow: unset; + width: unset; +} +#buckets.fullscreen .bucketTitle { + display: none; +} +#buckets.fullscreen .participantInfo { + display: none; +} +#buckets.fullscreen .participant { + border-radius: 0; + border: none; +} .bucketTitle > button { margin: 0.25em; margin-right: 0.5em; @@ -464,12 +495,65 @@ .muted { border: 1px solid #d00; } +#leavePresentationMode { + display: none; +} .participantInfo { margin: 0.25em; } -.participant > video { +.participant > video, .participant > img { width: 160px; } +#buckets.fullscreen .participant > video, #buckets.fullscreen .participant > img { + width: 100%; +} +#buckets.fullscreen .participant { + width: 100%; + background-color: black; +} + +#buckets.fullscreen .bucket { + width: 16.666666vw; + height: 100vh; + background-color: black; +} +/* none of this is actualy hooked up, since today there are alwas six */ +#buckets.fullscreen .bucket:first-of-type:nth-last-of-type(1) { + width: 100vw; + height: 100vh; +} +#buckets.fullscreen .bucket:first-of-type:nth-last-of-type(2), +#buckets.fullscreen .bucket:first-of-type:nth-last-of-type(2) ~ .bucket { + width: 50vw; + height: 100vh; +} +#buckets.fullscreen .bucket:first-of-type:nth-last-of-type(3), +#buckets.fullscreen .bucket:first-of-type:nth-last-of-type(3) ~ .bucket { + width: 33.33333vw; + height: 100vh; +} +#buckets.fullscreen .bucket:first-of-type:nth-last-of-type(4), +#buckets.fullscreen .bucket:first-of-type:nth-last-of-type(4) ~ .bucket { + width: 50vw; + height: 50vh; +} +#buckets.fullscreen .bucket:first-of-type:nth-last-of-type(5), +#buckets.fullscreen .bucket:first-of-type:nth-last-of-type(5) ~ .bucket { + width: 33.333333vw; + height: 50vh; +} +#buckets.fullscreen .bucket:first-of-type:nth-last-of-type(6), +#buckets.fullscreen .bucket:first-of-type:nth-last-of-type(6) ~ .bucket { + width: 33.333333vw; + height: 50vh; +} + +#buckets.fullscreen #leavePresentationMode { + display: block; + position: fixed; + right: 0.5em; + bottom: 0.5em; +} #needName, #wrongPassword { display: none; @@ -645,6 +729,11 @@
+ Presentation mode: + + +