add options pane, add ping volume and hide player controls settings
This commit is contained in:
		
							parent
							
								
									e43184ab49
								
							
						
					
					
						commit
						bcd36e2269
					
				
					 6 changed files with 644 additions and 489 deletions
				
			
		|  | @ -53,17 +53,52 @@ | ||||||
| 
 | 
 | ||||||
|     <div id="video-container"></div> |     <div id="video-container"></div> | ||||||
|     <div id="chatbox-container"> |     <div id="chatbox-container"> | ||||||
|       <div id="viewer-list"></div> |       <section id="viewing"> | ||||||
|       <div id="chatbox"></div> |         <div id="viewer-list"></div> | ||||||
|       <form id="chatbox-send"> |         <div id="chatbox"></div> | ||||||
|         <input |         <form id="chatbox-send"> | ||||||
|           type="text" |           <input | ||||||
|           placeholder="Message... (/help for commands)" |             type="text" | ||||||
|           list="emoji-autocomplete" |             placeholder="Message... (/help for commands)" | ||||||
|         /> |             list="emoji-autocomplete" | ||||||
|         <div id="emoji-autocomplete"></div> |           /> | ||||||
|         <!-- DO NOT ADD SPACING INSIDE THE TAG IT WILL BREAK THE CSS kthxbye --> |           <div id="emoji-autocomplete"></div> | ||||||
|       </form> |           <!-- DO NOT ADD SPACING INSIDE THE TAG IT WILL BREAK THE CSS kthxbye --> | ||||||
|  |         </form> | ||||||
|  |       </section> | ||||||
|  |       <section id="options"> | ||||||
|  |         <h2>settings</h2> | ||||||
|  |         <hr /> | ||||||
|  |         <form id="options-form"> | ||||||
|  |           <label for="plingVolume" | ||||||
|  |             ><input | ||||||
|  |               type="range" | ||||||
|  |               min="0" | ||||||
|  |               max="100" | ||||||
|  |               value="100" | ||||||
|  |               id="plingVolume" | ||||||
|  |               onchange="handlePlingVolume(this)" | ||||||
|  |             /> | ||||||
|  |             ping volume</label | ||||||
|  |           > | ||||||
|  |           <label | ||||||
|  |           ><input | ||||||
|  |             id="playerControlsShown" | ||||||
|  |             type="checkbox" | ||||||
|  |             onchange="togglePlayerControlsShown(this)" | ||||||
|  |           />hide controls when loading video player</label | ||||||
|  |         > | ||||||
|  |         </form> | ||||||
|  |       </section> | ||||||
|  |       <div id="options-toggle"> | ||||||
|  |         <button | ||||||
|  |           aria-label="settings" | ||||||
|  |           id="options-icon" | ||||||
|  |           onclick="toggleOptionPane(event, this)" | ||||||
|  |         > | ||||||
|  |           ⚙️ | ||||||
|  |         </button> | ||||||
|  |       </div> | ||||||
|     </div> |     </div> | ||||||
| 
 | 
 | ||||||
|     <script type="module" src="/main.mjs?v=bfdcf2"></script> |     <script type="module" src="/main.mjs?v=bfdcf2"></script> | ||||||
|  |  | ||||||
							
								
								
									
										43
									
								
								frontend/lib/options-pane.mjs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								frontend/lib/options-pane.mjs
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,43 @@ | ||||||
|  | export const toggleOptionPane = (event, element) => { | ||||||
|  |   event.preventDefault(); | ||||||
|  |   // show options
 | ||||||
|  |   if ( | ||||||
|  |     !document.querySelector("#options").style.display || | ||||||
|  |     document.querySelector("#options").style.display === "none" | ||||||
|  |   ) { | ||||||
|  |     // using this to do any potential init logic for the fields too
 | ||||||
|  |     loadPlayerControlsShown(document.querySelector("#playerControlsShown")) | ||||||
|  |     loadPlingVolume(document.querySelector("#plingVolume")) | ||||||
|  | 
 | ||||||
|  |     element.innerText = "❌"; | ||||||
|  |     document.querySelector("#options").style.display = "block"; | ||||||
|  |     return (document.querySelector("#viewing").style.display = "none"); | ||||||
|  |   } | ||||||
|  |   // hide options
 | ||||||
|  |   element.innerText = "⚙️"; | ||||||
|  |   document.querySelector("#options").style.display = "none"; | ||||||
|  |   document.querySelector("#viewing").style.display = "block"; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | const getPlayerControlsShown = () =>  localStorage.getItem("watch-party-default-allow-controls") || false | ||||||
|  | // delete from storage on false to prevent weird js boolean parsing (Boolean('false') === True)
 | ||||||
|  | const setPlayerControlShown = (boolean) => !boolean  | ||||||
|  | ? localStorage.removeItem("watch-party-default-allow-controls") | ||||||
|  | : localStorage.setItem("watch-party-default-allow-controls", boolean) | ||||||
|  | export const togglePlayerControlsShown = (element) => { | ||||||
|  |   const isShown = element.checked | ||||||
|  |   setPlayerControlShown(!isShown) | ||||||
|  | } | ||||||
|  | const loadPlayerControlsShown = (element) => { | ||||||
|  |   const isShown = getPlayerControlsShown() | ||||||
|  |   element.checked = !isShown | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | const getPlingVolume = () =>  localStorage.getItem("watch-party-pling-volume") || 100 | ||||||
|  | const setPlingVolume = (value) => localStorage.setItem("watch-party-pling-volume", value) | ||||||
|  | export const handlePlingVolume = (element) => { | ||||||
|  |   setPlingVolume(element.value) | ||||||
|  | } | ||||||
|  | const loadPlingVolume = (element) => { | ||||||
|  |   element.value = getPlingVolume() | ||||||
|  | } | ||||||
|  | @ -1,80 +1,82 @@ | ||||||
| export const pling = () => { | export const pling = () => { | ||||||
|   const maxGain = 0.3; |   // technically volume 0 breaks it but its the wanted outcome i guess?
 | ||||||
|   const duration = 0.22; |   const maxGain = | ||||||
|   const fadeDuration = 0.1; |     (Number(localStorage.getItem("watch-party-pling-volume")) / 100 ?? 1) * 0.3; | ||||||
|   const secondBeepOffset = 0.05; | 
 | ||||||
|   const thirdBeepOffset = 2 * secondBeepOffset; |   const duration = 0.22; | ||||||
| 
 |   const fadeDuration = 0.1; | ||||||
|   const ctx = new AudioContext(); |   const secondBeepOffset = 0.05; | ||||||
| 
 |   const thirdBeepOffset = 2 * secondBeepOffset; | ||||||
|   const firstBeepGain = ctx.createGain(); | 
 | ||||||
|   firstBeepGain.connect(ctx.destination); |   const ctx = new AudioContext(); | ||||||
|   firstBeepGain.gain.setValueAtTime(0.01, ctx.currentTime); | 
 | ||||||
|   firstBeepGain.gain.exponentialRampToValueAtTime( |   const firstBeepGain = ctx.createGain(); | ||||||
|     maxGain, |   firstBeepGain.connect(ctx.destination); | ||||||
|     ctx.currentTime + fadeDuration |   firstBeepGain.gain.setValueAtTime(0.01, ctx.currentTime); | ||||||
|   ); |   firstBeepGain.gain.exponentialRampToValueAtTime( | ||||||
|   firstBeepGain.gain.setValueAtTime( |     maxGain, | ||||||
|     maxGain, |     ctx.currentTime + fadeDuration | ||||||
|     ctx.currentTime + (duration - fadeDuration) |   ); | ||||||
|   ); |   firstBeepGain.gain.setValueAtTime( | ||||||
|   firstBeepGain.gain.exponentialRampToValueAtTime( |     maxGain, | ||||||
|     0.01, |     ctx.currentTime + (duration - fadeDuration) | ||||||
|     ctx.currentTime + duration |   ); | ||||||
|   ); |   firstBeepGain.gain.exponentialRampToValueAtTime( | ||||||
| 
 |     0.01, | ||||||
|   const firstBeep = ctx.createOscillator(); |     ctx.currentTime + duration | ||||||
|   firstBeep.connect(firstBeepGain); |   ); | ||||||
|   firstBeep.frequency.value = 400; | 
 | ||||||
|   firstBeep.type = "sine"; |   const firstBeep = ctx.createOscillator(); | ||||||
| 
 |   firstBeep.connect(firstBeepGain); | ||||||
|   const secondBeepGain = ctx.createGain(); |   firstBeep.frequency.value = 400; | ||||||
|   secondBeepGain.connect(ctx.destination); |   firstBeep.type = "sine"; | ||||||
|   secondBeepGain.gain.setValueAtTime(0.01, ctx.currentTime + secondBeepOffset); | 
 | ||||||
|   secondBeepGain.gain.exponentialRampToValueAtTime( |   const secondBeepGain = ctx.createGain(); | ||||||
|     maxGain, |   secondBeepGain.connect(ctx.destination); | ||||||
|     ctx.currentTime + secondBeepOffset + fadeDuration |   secondBeepGain.gain.setValueAtTime(0.01, ctx.currentTime + secondBeepOffset); | ||||||
|   ); |   secondBeepGain.gain.exponentialRampToValueAtTime( | ||||||
|   secondBeepGain.gain.setValueAtTime( |     maxGain, | ||||||
|     maxGain, |     ctx.currentTime + secondBeepOffset + fadeDuration | ||||||
|     ctx.currentTime + secondBeepOffset + (duration - fadeDuration) |   ); | ||||||
|   ); |   secondBeepGain.gain.setValueAtTime( | ||||||
|   secondBeepGain.gain.exponentialRampToValueAtTime( |     maxGain, | ||||||
|     0.01, |     ctx.currentTime + secondBeepOffset + (duration - fadeDuration) | ||||||
|     ctx.currentTime + secondBeepOffset + duration |   ); | ||||||
|   ); |   secondBeepGain.gain.exponentialRampToValueAtTime( | ||||||
| 
 |     0.01, | ||||||
|   const secondBeep = ctx.createOscillator(); |     ctx.currentTime + secondBeepOffset + duration | ||||||
|   secondBeep.connect(secondBeepGain); |   ); | ||||||
|   secondBeep.frequency.value = 600; | 
 | ||||||
|   secondBeep.type = "sine"; |   const secondBeep = ctx.createOscillator(); | ||||||
| 
 |   secondBeep.connect(secondBeepGain); | ||||||
|   const thirdBeepGain = ctx.createGain(); |   secondBeep.frequency.value = 600; | ||||||
|   thirdBeepGain.connect(ctx.destination); |   secondBeep.type = "sine"; | ||||||
|   thirdBeepGain.gain.setValueAtTime(0.01, ctx.currentTime + thirdBeepOffset); | 
 | ||||||
|   thirdBeepGain.gain.exponentialRampToValueAtTime( |   const thirdBeepGain = ctx.createGain(); | ||||||
|     maxGain, |   thirdBeepGain.connect(ctx.destination); | ||||||
|     ctx.currentTime + thirdBeepOffset + fadeDuration |   thirdBeepGain.gain.setValueAtTime(0.01, ctx.currentTime + thirdBeepOffset); | ||||||
|   ); |   thirdBeepGain.gain.exponentialRampToValueAtTime( | ||||||
|   thirdBeepGain.gain.setValueAtTime( |     maxGain, | ||||||
|     maxGain, |     ctx.currentTime + thirdBeepOffset + fadeDuration | ||||||
|     ctx.currentTime + thirdBeepOffset + (duration - fadeDuration) |   ); | ||||||
|   ); |   thirdBeepGain.gain.setValueAtTime( | ||||||
|   thirdBeepGain.gain.exponentialRampToValueAtTime( |     maxGain, | ||||||
|     0.01, |     ctx.currentTime + thirdBeepOffset + (duration - fadeDuration) | ||||||
|     ctx.currentTime + thirdBeepOffset + duration |   ); | ||||||
|   ); |   thirdBeepGain.gain.exponentialRampToValueAtTime( | ||||||
| 
 |     0.01, | ||||||
|   const thirdBeep = ctx.createOscillator(); |     ctx.currentTime + thirdBeepOffset + duration | ||||||
|   thirdBeep.connect(thirdBeepGain); |   ); | ||||||
|   thirdBeep.frequency.value = 900; | 
 | ||||||
|   thirdBeep.type = "sine"; |   const thirdBeep = ctx.createOscillator(); | ||||||
| 
 |   thirdBeep.connect(thirdBeepGain); | ||||||
|   firstBeep.start(ctx.currentTime); |   thirdBeep.frequency.value = 900; | ||||||
|   firstBeep.stop(ctx.currentTime + duration); |   thirdBeep.type = "sine"; | ||||||
|   secondBeep.start(ctx.currentTime + secondBeepOffset); | 
 | ||||||
|   secondBeep.stop(ctx.currentTime + (secondBeepOffset + duration)); |   firstBeep.start(ctx.currentTime); | ||||||
|   thirdBeep.start(ctx.currentTime + thirdBeepOffset); |   firstBeep.stop(ctx.currentTime + duration); | ||||||
|   thirdBeep.stop(ctx.currentTime + (thirdBeepOffset + duration)); |   secondBeep.start(ctx.currentTime + secondBeepOffset); | ||||||
| }; |   secondBeep.stop(ctx.currentTime + (secondBeepOffset + duration)); | ||||||
| 
 |   thirdBeep.start(ctx.currentTime + thirdBeepOffset); | ||||||
|  |   thirdBeep.stop(ctx.currentTime + (thirdBeepOffset + duration)); | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | @ -228,7 +228,6 @@ export const joinSession = async () => { | ||||||
|       is_playing |       is_playing | ||||||
|     ); |     ); | ||||||
| 
 | 
 | ||||||
|     // TODO: Allow the user to set this somewhere
 |  | ||||||
|     let defaultAllowControls = false; |     let defaultAllowControls = false; | ||||||
|     try { |     try { | ||||||
|       defaultAllowControls = localStorage.getItem( |       defaultAllowControls = localStorage.getItem( | ||||||
|  |  | ||||||
|  | @ -1,7 +1,15 @@ | ||||||
| import { setupJoinSessionForm } from "./lib/join-session.mjs?v=bfdcf2"; | import { setupJoinSessionForm } from "./lib/join-session.mjs?v=bfdcf2"; | ||||||
|  | import { | ||||||
|  |   toggleOptionPane, | ||||||
|  |   togglePlayerControlsShown, | ||||||
|  |   handlePlingVolume | ||||||
|  | } from "./lib/options-pane.mjs?v=bfdcf2"; | ||||||
| 
 | 
 | ||||||
| const main = () => { | const main = () => { | ||||||
|   setupJoinSessionForm(); |   setupJoinSessionForm(); | ||||||
|  |   window.toggleOptionPane = toggleOptionPane; | ||||||
|  |   window.togglePlayerControlsShown = togglePlayerControlsShown; | ||||||
|  |   window.handlePlingVolume = handlePlingVolume | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| if (document.readyState === "complete") { | if (document.readyState === "complete") { | ||||||
|  |  | ||||||
|  | @ -1,397 +1,465 @@ | ||||||
| *, | *, | ||||||
| *:before, | *:before, | ||||||
| *:after { | *:after { | ||||||
|   box-sizing: border-box; |   box-sizing: border-box; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| :root { | :root { | ||||||
|   --bg-rgb: 28, 23, 36; |   --bg-rgb: 28, 23, 36; | ||||||
|   --fg-rgb: 234, 234, 248; |   --fg-rgb: 234, 234, 248; | ||||||
|   --accent-rgb: 181, 127, 220; |   --accent-rgb: 181, 127, 220; | ||||||
|   --fg: rgb(var(--fg-rgb)); |   --accent-darker: rgb(95, 37, 136); /*50% darker*/ | ||||||
|   --bg: rgb(var(--bg-rgb)); |   --accent-darkest: rgb(47, 19, 68); /*75% darker*/ | ||||||
|   --default-user-color: rgb(126, 208, 255); |   --fg: rgb(var(--fg-rgb)); | ||||||
|   --accent: rgb(var(--accent-rgb)); |   --bg: rgb(var(--bg-rgb)); | ||||||
|   --fg-transparent: rgba(var(--fg-rgb), 0.25); |   --default-user-color: rgb(126, 208, 255); | ||||||
|   --bg-transparent: rgba(var(--bg-rgb), 0.25); |   --accent: rgb(var(--accent-rgb)); | ||||||
|   --autocomplete-bg: linear-gradient( |   --fg-transparent: rgba(var(--fg-rgb), 0.25); | ||||||
|       var(--fg-transparent), |   --bg-transparent: rgba(var(--bg-rgb), 0.25); | ||||||
|       var(--fg-transparent) |   --autocomplete-bg: linear-gradient( | ||||||
|     ), |       var(--fg-transparent), | ||||||
|     linear-gradient(var(--bg), var(--bg)); |       var(--fg-transparent) | ||||||
|   --chip-bg: linear-gradient( |     ), | ||||||
|       var(--accent-transparent), |     linear-gradient(var(--bg), var(--bg)); | ||||||
|       var(--accent-transparent) |   --chip-bg: linear-gradient( | ||||||
|     ), |       var(--accent-transparent), | ||||||
|     linear-gradient(var(--bg), var(--bg)); |       var(--accent-transparent) | ||||||
|   --accent-transparent: rgba(var(--accent-rgb), 0.25); |     ), | ||||||
| } |     linear-gradient(var(--bg), var(--bg)); | ||||||
| 
 |   --accent-transparent: rgba(var(--accent-rgb), 0.25); | ||||||
| html { | } | ||||||
|   background-color: var(--bg); | 
 | ||||||
|   color: var(--fg); | html { | ||||||
|   font-size: 1.125rem; |   background-color: var(--bg); | ||||||
|   font-family: sans-serif; |   color: var(--fg); | ||||||
| } |   font-size: 1.125rem; | ||||||
| 
 |   font-family: sans-serif; | ||||||
| html, | } | ||||||
| body { | 
 | ||||||
|   margin: 0; | html, | ||||||
|   padding: 0; | body { | ||||||
|   overflow: hidden; |   margin: 0; | ||||||
|   overscroll-behavior: none; |   padding: 0; | ||||||
|   width: 100%; |   overflow: hidden; | ||||||
|   height: 100%; |   overscroll-behavior: none; | ||||||
| } |   width: 100%; | ||||||
| 
 |   height: 100%; | ||||||
| body { | } | ||||||
|   display: flex; | 
 | ||||||
|   flex-direction: column; | body { | ||||||
| } |   display: flex; | ||||||
| 
 |   flex-direction: column; | ||||||
| video { | } | ||||||
|   display: block; | 
 | ||||||
|   width: 100%; | video { | ||||||
|   height: 100%; |   display: block; | ||||||
|   object-fit: contain; |   width: 100%; | ||||||
| } |   height: 100%; | ||||||
| 
 |   object-fit: contain; | ||||||
| #video-container { | } | ||||||
|   flex-grow: 0; | 
 | ||||||
|   flex-shrink: 1; | #video-container { | ||||||
|   display: none; |   flex-grow: 0; | ||||||
| } |   flex-shrink: 1; | ||||||
| 
 |   display: none; | ||||||
| a { | } | ||||||
|   color: var(--accent); | 
 | ||||||
| } | a { | ||||||
| 
 |   color: var(--accent); | ||||||
| .chip { | } | ||||||
|   color: var(--fg); | 
 | ||||||
|   background: var(--chip-bg); | .chip { | ||||||
|   text-decoration: none; |   color: var(--fg); | ||||||
|   padding: 0 0.5rem 0 1.45rem; |   background: var(--chip-bg); | ||||||
|   display: inline-flex; |   text-decoration: none; | ||||||
|   position: relative; |   padding: 0 0.5rem 0 1.45rem; | ||||||
|   font-size: 0.9rem; |   display: inline-flex; | ||||||
|   height: 1.125rem; |   position: relative; | ||||||
|   align-items: center; |   font-size: 0.9rem; | ||||||
|   border-radius: 2rem; |   height: 1.125rem; | ||||||
|   overflow: hidden; |   align-items: center; | ||||||
| } |   border-radius: 2rem; | ||||||
| 
 |   overflow: hidden; | ||||||
| .chip::before { | } | ||||||
|   content: ""; | 
 | ||||||
|   position: absolute; | .chip::before { | ||||||
|   left: 0; |   content: ""; | ||||||
|   top: 0; |   position: absolute; | ||||||
|   width: 1.125rem; |   left: 0; | ||||||
|   height: 100%; |   top: 0; | ||||||
|   display: flex; |   width: 1.125rem; | ||||||
|   align-items: center; |   height: 100%; | ||||||
|   justify-content: center; |   display: flex; | ||||||
|   text-align: center; |   align-items: center; | ||||||
|   background: var(--accent-transparent); |   justify-content: center; | ||||||
|   background-repeat: no-repeat; |   text-align: center; | ||||||
|   background-size: 18px; |   background: var(--accent-transparent); | ||||||
|   background-position: center; |   background-repeat: no-repeat; | ||||||
| } |   background-size: 18px; | ||||||
| 
 |   background-position: center; | ||||||
| .join-chip::before { | } | ||||||
|   background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0iI2ZmZiI+PHBhdGggZD0iTTggNXYxNGwxMS03eiIvPjwvc3ZnPg=="); | 
 | ||||||
| } | .join-chip::before { | ||||||
| 
 |   background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0iI2ZmZiI+PHBhdGggZD0iTTggNXYxNGwxMS03eiIvPjwvc3ZnPg=="); | ||||||
| .time-chip::before { | } | ||||||
|   background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0iI2ZmZiI+PHBhdGggZD0iTTExLjk5IDJDNi40NyAyIDIgNi40OCAyIDEyczQuNDcgMTAgOS45OSAxMEMxNy41MiAyMiAyMiAxNy41MiAyMiAxMlMxNy41MiAyIDExLjk5IDJ6TTEyIDIwYy00LjQyIDAtOC0zLjU4LTgtOHMzLjU4LTggOC04IDggMy41OCA4IDgtMy41OCA4LTggOHoiLz48cGF0aCBkPSJNMTIuNSA3SDExdjZsNS4yNSAzLjE1Ljc1LTEuMjMtNC41LTIuNjd6Ii8+PC9zdmc+"); | 
 | ||||||
| } | .time-chip::before { | ||||||
| 
 |   background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0iI2ZmZiI+PHBhdGggZD0iTTExLjk5IDJDNi40NyAyIDIgNi40OCAyIDEyczQuNDcgMTAgOS45OSAxMEMxNy41MiAyMiAyMiAxNy41MiAyMiAxMlMxNy41MiAyIDExLjk5IDJ6TTEyIDIwYy00LjQyIDAtOC0zLjU4LTgtOHMzLjU4LTggOC04IDggMy41OCA4IDgtMy41OCA4LTggOHoiLz48cGF0aCBkPSJNMTIuNSA3SDExdjZsNS4yNSAzLjE1Ljc1LTEuMjMtNC41LTIuNjd6Ii8+PC9zdmc+"); | ||||||
| label { | } | ||||||
|   display: block; | 
 | ||||||
| } | label { | ||||||
| 
 |   display: block; | ||||||
| input[type="url"], | } | ||||||
| input[type="text"] { | 
 | ||||||
|   background: #fff; | input[type="url"], | ||||||
|   background-clip: padding-box; | input[type="text"] { | ||||||
|   border: 1px solid rgba(0, 0, 0, 0.12); |   background: #fff; | ||||||
|   border-radius: 6px; |   background-clip: padding-box; | ||||||
|   color: rgba(0, 0, 0, 0.8); |   border: 1px solid rgba(0, 0, 0, 0.12); | ||||||
|   display: block; |   border-radius: 6px; | ||||||
| 
 |   color: rgba(0, 0, 0, 0.8); | ||||||
|   margin: 0.5em 0; |   display: block; | ||||||
|   padding: 0.5em 1em; | 
 | ||||||
|   line-height: 1.5; |   margin: 0.5em 0; | ||||||
| 
 |   padding: 0.5em 1em; | ||||||
|   font-family: sans-serif; |   line-height: 1.5; | ||||||
|   font-size: 1em; | 
 | ||||||
|   width: 100%; |   font-family: sans-serif; | ||||||
| 
 |   font-size: 1em; | ||||||
|   resize: none; |   width: 100%; | ||||||
|   overflow-x: wrap; | 
 | ||||||
|   overflow-y: scroll; |   resize: none; | ||||||
| } |   overflow-x: wrap; | ||||||
| 
 |   overflow-y: scroll; | ||||||
| button { | } | ||||||
|   background-color: var(--accent); | 
 | ||||||
|   border: var(--accent); | button { | ||||||
|   border-radius: 6px; |   background-color: var(--accent); | ||||||
|   color: #fff; |   border: var(--accent); | ||||||
|   padding: 0.5em 1em; |   border-radius: 6px; | ||||||
|   display: inline-block; |   color: #fff; | ||||||
|   font-weight: 400; |   padding: 0.5em 1em; | ||||||
|   text-align: center; |   display: inline-block; | ||||||
|   white-space: nowrap; |   font-weight: 400; | ||||||
|   vertical-align: middle; |   text-align: center; | ||||||
| 
 |   white-space: nowrap; | ||||||
|   font-family: sans-serif; |   vertical-align: middle; | ||||||
|   font-size: 1em; | 
 | ||||||
|   width: 100%; |   font-family: sans-serif; | ||||||
| 
 |   font-size: 1em; | ||||||
|   user-select: none; |   width: 100%; | ||||||
|   border: 1px solid rgba(0, 0, 0, 0); | 
 | ||||||
|   line-height: 1.5; |   user-select: none; | ||||||
|   cursor: pointer; |   border: 1px solid rgba(0, 0, 0, 0); | ||||||
|   margin: 0.5em 0; |   line-height: 1.5; | ||||||
| } |   cursor: pointer; | ||||||
| 
 |   margin: 0.5em 0; | ||||||
| button:disabled { | } | ||||||
|   filter: saturate(0.75); | 
 | ||||||
|   opacity: 0.75; | button:disabled { | ||||||
|   cursor: default; |   filter: saturate(0.75); | ||||||
| } |   opacity: 0.75; | ||||||
| 
 |   cursor: default; | ||||||
| button.small-button { | } | ||||||
|   font-size: 0.75em; | 
 | ||||||
|   padding-top: 0; | button.small-button { | ||||||
|   padding-bottom: 0; |   font-size: 0.75em; | ||||||
| } |   padding-top: 0; | ||||||
| 
 |   padding-bottom: 0; | ||||||
| .subtitle-track-group { | } | ||||||
|   display: flex; | 
 | ||||||
| } | .subtitle-track-group { | ||||||
| 
 |   display: flex; | ||||||
| .subtitle-track-group > * { | } | ||||||
|   margin-top: 0 !important; | 
 | ||||||
|   margin-bottom: 0 !important; | .subtitle-track-group > * { | ||||||
|   margin-right: 1ch !important; |   margin-top: 0 !important; | ||||||
| } |   margin-bottom: 0 !important; | ||||||
| 
 |   margin-right: 1ch !important; | ||||||
| #pre-join-controls, | } | ||||||
| #create-controls { | 
 | ||||||
|   margin: 0; | #pre-join-controls, | ||||||
|   flex-grow: 1; | #create-controls { | ||||||
|   overflow-y: auto; |   margin: 0; | ||||||
|   display: flex; |   flex-grow: 1; | ||||||
|   flex-direction: column; |   overflow-y: auto; | ||||||
|   align-items: center; |   display: flex; | ||||||
|   justify-content: center; |   flex-direction: column; | ||||||
| } |   align-items: center; | ||||||
| 
 |   justify-content: center; | ||||||
| #join-session-form, | } | ||||||
| #create-session-form { | 
 | ||||||
|   width: 500px; | #join-session-form, | ||||||
|   max-width: 100%; | #create-session-form { | ||||||
|   padding: 1rem; |   width: 500px; | ||||||
| } |   max-width: 100%; | ||||||
| 
 |   padding: 1rem; | ||||||
| #join-session-form > *:first-child, | } | ||||||
| #create-session-form > *:first-child { | 
 | ||||||
|   margin-top: 0; | #join-session-form > *:first-child, | ||||||
| } | #create-session-form > *:first-child { | ||||||
| 
 |   margin-top: 0; | ||||||
| #post-create-message { | } | ||||||
|   display: none; | 
 | ||||||
|   width: 100%; | #post-create-message { | ||||||
|   font-size: 0.85em; |   display: none; | ||||||
| } |   width: 100%; | ||||||
| 
 |   font-size: 0.85em; | ||||||
| #chatbox-container { | } | ||||||
|   display: none; | 
 | ||||||
| } | #chatbox-container { | ||||||
| 
 |   display: none; | ||||||
| .chat-message { | } | ||||||
|   overflow-wrap: break-word; | 
 | ||||||
|   margin-bottom: 0.125rem; | .chat-message { | ||||||
| } |   overflow-wrap: break-word; | ||||||
| 
 |   margin-bottom: 0.125rem; | ||||||
| .chat-message > strong, | } | ||||||
| #viewer-list strong { | 
 | ||||||
|   color: var(--user-color, var(--default-user-color)); | .chat-message > strong, | ||||||
| } | #viewer-list strong { | ||||||
| 
 |   color: var(--user-color, var(--default-user-color)); | ||||||
| .chat-message.user-join, | } | ||||||
| .chat-message.user-leave, | 
 | ||||||
| .chat-message.ping { | .chat-message.user-join, | ||||||
|   font-style: italic; | .chat-message.user-leave, | ||||||
| } | .chat-message.ping { | ||||||
| 
 |   font-style: italic; | ||||||
| .chat-message.set-time, | } | ||||||
| .chat-message.set-playing, | 
 | ||||||
| .chat-message.join-session { | .chat-message.set-time, | ||||||
|   font-style: italic; | .chat-message.set-playing, | ||||||
|   text-align: right; | .chat-message.join-session { | ||||||
|   font-size: 0.85em; |   font-style: italic; | ||||||
| } |   text-align: right; | ||||||
| 
 |   font-size: 0.85em; | ||||||
| .chat-message.command-message { | } | ||||||
|   font-size: 0.85em; | 
 | ||||||
| } | .chat-message.command-message { | ||||||
| 
 |   font-size: 0.85em; | ||||||
| .chat-message.set-time > strong, | } | ||||||
| .chat-message.set-playing > strong, | 
 | ||||||
| .chat-message.join-session > strong { | .chat-message.set-time > strong, | ||||||
|   color: unset !important; | .chat-message.set-playing > strong, | ||||||
| } | .chat-message.join-session > strong { | ||||||
| 
 |   color: unset !important; | ||||||
| .emoji { | } | ||||||
|   width: 2ch; | 
 | ||||||
|   height: 2ch; | .emoji { | ||||||
|   object-fit: contain; |   width: 2ch; | ||||||
|   margin-bottom: -0.35ch; |   height: 2ch; | ||||||
| } |   object-fit: contain; | ||||||
| 
 |   margin-bottom: -0.35ch; | ||||||
| #chatbox { | } | ||||||
|   padding: 0.5em 1em; | 
 | ||||||
|   overflow-y: scroll; | #chatbox { | ||||||
|   flex-shrink: 1; |   padding: 0.5em 1em; | ||||||
|   flex-grow: 1; |   overflow-y: scroll; | ||||||
| } |   flex-shrink: 1; | ||||||
| 
 |   flex-grow: 1; | ||||||
| #viewer-list { | } | ||||||
|   padding: 0.5em 1em; | 
 | ||||||
|   /* TODO: turn this into max-height instead of fixed height without breaking the chatbox height */ | #viewer-list { | ||||||
|   overflow-y: scroll; |   padding: 0.5em 1em; | ||||||
|   border-bottom: var(--fg-transparent); |   /* TODO: turn this into max-height instead of fixed height without breaking the chatbox height */ | ||||||
|   border-bottom-style: solid; |   overflow-y: scroll; | ||||||
|   max-height: 4rem; |   border-bottom: var(--fg-transparent); | ||||||
|   flex-shrink: 0; |   border-bottom-style: solid; | ||||||
| } |   max-height: 4rem; | ||||||
| 
 |   flex-shrink: 0; | ||||||
| #chatbox-container { | } | ||||||
|   background-color: var(--bg); | 
 | ||||||
|   flex-direction: column; | #chatbox-container { | ||||||
|   flex-grow: 1; |   background-color: var(--bg); | ||||||
|   flex-shrink: 1; |   flex-direction: column; | ||||||
|   flex-basis: 36ch; |   flex-grow: 1; | ||||||
|   min-width: 36ch; |   flex-shrink: 1; | ||||||
|   overflow: hidden; |   flex-basis: 36ch; | ||||||
| } |   min-width: 36ch; | ||||||
| 
 |   overflow: hidden; | ||||||
| #chatbox-send { | } | ||||||
|   padding: 0 1em; | 
 | ||||||
|   padding-bottom: 0.5em; | #chatbox-send { | ||||||
|   position: relative; |   padding: 0 1em; | ||||||
| } |   position: relative; | ||||||
| 
 | } | ||||||
| #chatbox-send > input { | 
 | ||||||
|   font-size: 0.75em; | #chatbox-send > input { | ||||||
|   width: 100%; |   font-size: 0.75em; | ||||||
| } |   width: 100%; | ||||||
| 
 | } | ||||||
| #emoji-autocomplete { | 
 | ||||||
|   position: absolute; | #emoji-autocomplete { | ||||||
|   bottom: 3.25rem; |   position: absolute; | ||||||
|   background-image: var(--autocomplete-bg); |   bottom: 3.25rem; | ||||||
|   border-radius: 6px; |   background-image: var(--autocomplete-bg); | ||||||
|   width: calc(100% - 2rem); |   border-radius: 6px; | ||||||
|   max-height: 8.5rem; |   width: calc(100% - 2rem); | ||||||
|   overflow-y: auto; |   max-height: 8.5rem; | ||||||
|   clip-path: inset(0 0 0 0 round 8px); |   overflow-y: auto; | ||||||
| } |   clip-path: inset(0 0 0 0 round 8px); | ||||||
| 
 | } | ||||||
| #emoji-autocomplete:empty { | 
 | ||||||
|   display: none; | #emoji-autocomplete:empty { | ||||||
| } |   display: none; | ||||||
| 
 | } | ||||||
| .emoji-option { | 
 | ||||||
|   background: transparent; | .emoji-option { | ||||||
|   font-size: 0.75rem; |   background: transparent; | ||||||
|   text-align: left; |   font-size: 0.75rem; | ||||||
|   margin: 0 0.25rem; |   text-align: left; | ||||||
|   border-radius: 4px; |   margin: 0 0.25rem; | ||||||
|   width: calc(100% - 0.5rem); |   border-radius: 4px; | ||||||
|   display: flex; |   width: calc(100% - 0.5rem); | ||||||
|   align-items: center; |   display: flex; | ||||||
|   padding: 0.25rem 0.5rem; |   align-items: center; | ||||||
|   scroll-margin: 0.25rem; |   padding: 0.25rem 0.5rem; | ||||||
| } |   scroll-margin: 0.25rem; | ||||||
| 
 | } | ||||||
| .emoji-option:first-child { | 
 | ||||||
|   margin-top: 0.25rem; | .emoji-option:first-child { | ||||||
| } |   margin-top: 0.25rem; | ||||||
| 
 | } | ||||||
| .emoji-option:last-child { | 
 | ||||||
|   margin-bottom: 0.25rem; | .emoji-option:last-child { | ||||||
| } |   margin-bottom: 0.25rem; | ||||||
| 
 | } | ||||||
| .emoji-option .emoji { | 
 | ||||||
|   width: 1.25rem; | .emoji-option .emoji { | ||||||
|   height: 1.25rem; |   width: 1.25rem; | ||||||
|   margin: 0 0.5rem 0 0; |   height: 1.25rem; | ||||||
|   font-size: 2.25ch; |   margin: 0 0.5rem 0 0; | ||||||
|   display: flex; |   font-size: 2.25ch; | ||||||
|   align-items: center; |   display: flex; | ||||||
|   justify-content: center; |   align-items: center; | ||||||
|   overflow: hidden; |   justify-content: center; | ||||||
|   flex-shrink: 0; |   overflow: hidden; | ||||||
| } |   flex-shrink: 0; | ||||||
| 
 | } | ||||||
| .emoji-name { | 
 | ||||||
|   overflow: hidden; | .emoji-name { | ||||||
|   text-overflow: ellipsis; |   overflow: hidden; | ||||||
| } |   text-overflow: ellipsis; | ||||||
| 
 | } | ||||||
| .emoji-option.selected { | 
 | ||||||
|   background: var(--fg-transparent); | .emoji-option.selected { | ||||||
| } |   background: var(--fg-transparent); | ||||||
| 
 | } | ||||||
| #join-session-colour { | 
 | ||||||
|   -moz-appearance: none; | #join-session-colour { | ||||||
|   -webkit-appearance: none; |   -moz-appearance: none; | ||||||
|   appearance: none; |   -webkit-appearance: none; | ||||||
|   border: none; |   appearance: none; | ||||||
|   padding: 0; |   border: none; | ||||||
|   border-radius: 6px; |   padding: 0; | ||||||
|   overflow: hidden; |   border-radius: 6px; | ||||||
|   margin: 0.5em 0; |   overflow: hidden; | ||||||
|   height: 2rem; |   margin: 0.5em 0; | ||||||
|   width: 2.5rem; |   height: 2rem; | ||||||
|   cursor: pointer; |   width: 2.5rem; | ||||||
| } |   cursor: pointer; | ||||||
| 
 | } | ||||||
| input[type="color"]::-moz-color-swatch { | 
 | ||||||
|   border: none; | #options-toggle { | ||||||
|   margin: 0; |   padding: 0 1em 1em; | ||||||
|   padding: 0; |   position: relative; | ||||||
| } |   text-align: right; | ||||||
| 
 |   margin-top: auto; | ||||||
| input[type="color"]::-webkit-color-swatch { | } | ||||||
|   border: none; | 
 | ||||||
|   margin: 0; | #options-toggle #options-icon { | ||||||
|   padding: 0; |   padding: 3px 10px; | ||||||
| } |   font-size: 1em; | ||||||
| 
 |   max-width: 3em; | ||||||
| input[type="color"]::-webkit-color-swatch-wrapper { | 
 | ||||||
|   border: none; |   color: transparent; | ||||||
|   margin: 0; |   text-shadow: 0 0 0 white; | ||||||
|   padding: 0; |   border: none; | ||||||
| } |   box-shadow:0px 0px 0px 2px var(--accent-darkest) inset; | ||||||
| 
 |    | ||||||
| @media (min-aspect-ratio: 4/3) { |   transform-style: preserve-3d; | ||||||
|   body { |   transition: cubic-bezier(0, 0, 0.58, 1), cubic-bezier(0, 0, 0.58, 1); | ||||||
|     flex-direction: row; |   transition-duration: 150ms; | ||||||
|   } | } | ||||||
| 
 | 
 | ||||||
|   #chatbox-container { | #options-toggle #options-icon::before { | ||||||
|     height: 100vh !important; |   content: ""; | ||||||
|     flex-grow: 0; | 
 | ||||||
|   } |   position: absolute; | ||||||
| 
 |    | ||||||
|   #video-container { |   width: 100%; | ||||||
|     flex-grow: 1; |   height: 100%; | ||||||
|   } |   top: 0; | ||||||
| 
 |   left: 0; | ||||||
|   #chatbox { |   right: 0; | ||||||
|     height: calc(100vh - 5em - 4em) !important; |   bottom: 0; | ||||||
|   } | 
 | ||||||
| } |   background-color: var(--accent-darker); | ||||||
|  |   border-radius: inherit; | ||||||
|  |   border: none; | ||||||
|  |   box-shadow:0px 0px 0px 2px var(--accent-darkest) inset; | ||||||
|  | 
 | ||||||
|  |   transform: translate3d(0, 0.5em, -1em); | ||||||
|  |   transition: cubic-bezier(0, 0, 0.58, 1), cubic-bezier(0, 0, 0.58, 1); | ||||||
|  |   transition-duration: 150ms; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #options-toggle #options-icon:hover { | ||||||
|  |   transform: translate(0, 0.15em); | ||||||
|  |   background-color: rgb(173, 113, 216); /*5% darker accent*/ | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #options-toggle #options-icon:hover::before { | ||||||
|  |   transform: translate3d(0, 0.35em, -1em); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #options-toggle #options-icon:active { | ||||||
|  |   transform: translate(0em, 0.5em); | ||||||
|  |   background-color: rgb(165, 100, 213); /*10% darker accent*/ | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #options-toggle #options-icon:active::before { | ||||||
|  |   transform: translate3d(0, 0, -1em); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #options { | ||||||
|  |   display: none; /* default for sections is block */ | ||||||
|  |   padding: 01em; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | input[type="color"]::-moz-color-swatch { | ||||||
|  |   border: none; | ||||||
|  |   margin: 0; | ||||||
|  |   padding: 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | input[type="color"]::-webkit-color-swatch { | ||||||
|  |   border: none; | ||||||
|  |   margin: 0; | ||||||
|  |   padding: 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | input[type="color"]::-webkit-color-swatch-wrapper { | ||||||
|  |   border: none; | ||||||
|  |   margin: 0; | ||||||
|  |   padding: 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | @media (min-aspect-ratio: 4/3) { | ||||||
|  |   body { | ||||||
|  |     flex-direction: row; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   #chatbox-container { | ||||||
|  |     height: 100vh !important; | ||||||
|  |     flex-grow: 0; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   #video-container { | ||||||
|  |     flex-grow: 1; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   #chatbox { | ||||||
|  |     height: calc(100vh - 5em - 4em) !important; | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue