add options pane, add ping volume and hide player controls settings #8
					 6 changed files with 644 additions and 489 deletions
				
			
		|  | @ -53,17 +53,52 @@ | |||
| 
 | ||||
|     <div id="video-container"></div> | ||||
|     <div id="chatbox-container"> | ||||
|       <div id="viewer-list"></div> | ||||
|       <div id="chatbox"></div> | ||||
|       <form id="chatbox-send"> | ||||
|         <input | ||||
|           type="text" | ||||
|           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 --> | ||||
|       </form> | ||||
|       <section id="viewing"> | ||||
|         <div id="viewer-list"></div> | ||||
|         <div id="chatbox"></div> | ||||
|         <form id="chatbox-send"> | ||||
|           <input | ||||
|             type="text" | ||||
|             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 --> | ||||
|         </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> | ||||
| 
 | ||||
|     <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,5 +1,8 @@ | |||
| export const pling = () => { | ||||
|   const maxGain = 0.3; | ||||
|   // technically volume 0 breaks it but its the wanted outcome i guess?
 | ||||
|   const maxGain = | ||||
|     (Number(localStorage.getItem("watch-party-pling-volume")) / 100 ?? 1) * 0.3; | ||||
| 
 | ||||
|   const duration = 0.22; | ||||
|   const fadeDuration = 0.1; | ||||
|   const secondBeepOffset = 0.05; | ||||
|  | @ -77,4 +80,3 @@ export const pling = () => { | |||
|   thirdBeep.start(ctx.currentTime + thirdBeepOffset); | ||||
|   thirdBeep.stop(ctx.currentTime + (thirdBeepOffset + duration)); | ||||
| }; | ||||
| 
 | ||||
|  |  | |||
|  | @ -228,7 +228,6 @@ export const joinSession = async () => { | |||
|       is_playing | ||||
|     ); | ||||
| 
 | ||||
|     // TODO: Allow the user to set this somewhere
 | ||||
|     let defaultAllowControls = false; | ||||
|     try { | ||||
|       defaultAllowControls = localStorage.getItem( | ||||
|  |  | |||
|  | @ -1,7 +1,15 @@ | |||
| import { setupJoinSessionForm } from "./lib/join-session.mjs?v=bfdcf2"; | ||||
| import { | ||||
|   toggleOptionPane, | ||||
|   togglePlayerControlsShown, | ||||
|   handlePlingVolume | ||||
| } from "./lib/options-pane.mjs?v=bfdcf2"; | ||||
| 
 | ||||
| const main = () => { | ||||
|   setupJoinSessionForm(); | ||||
|   window.toggleOptionPane = toggleOptionPane; | ||||
|   window.togglePlayerControlsShown = togglePlayerControlsShown; | ||||
|   window.handlePlingVolume = handlePlingVolume | ||||
| }; | ||||
| 
 | ||||
| if (document.readyState === "complete") { | ||||
|  |  | |||
|  | @ -8,6 +8,8 @@ | |||
|   --bg-rgb: 28, 23, 36; | ||||
|   --fg-rgb: 234, 234, 248; | ||||
|   --accent-rgb: 181, 127, 220; | ||||
|   --accent-darker: rgb(95, 37, 136); /*50% darker*/ | ||||
|   --accent-darkest: rgb(47, 19, 68); /*75% darker*/ | ||||
|   --fg: rgb(var(--fg-rgb)); | ||||
|   --bg: rgb(var(--bg-rgb)); | ||||
|   --default-user-color: rgb(126, 208, 255); | ||||
|  | @ -279,7 +281,6 @@ button.small-button { | |||
| 
 | ||||
| #chatbox-send { | ||||
|   padding: 0 1em; | ||||
|   padding-bottom: 0.5em; | ||||
|   position: relative; | ||||
| } | ||||
| 
 | ||||
|  | @ -359,6 +360,73 @@ button.small-button { | |||
|   cursor: pointer; | ||||
| } | ||||
| 
 | ||||
| #options-toggle { | ||||
|   padding: 0 1em 1em; | ||||
|   position: relative; | ||||
|   text-align: right; | ||||
|   margin-top: auto; | ||||
| } | ||||
| 
 | ||||
| #options-toggle #options-icon { | ||||
|   padding: 3px 10px; | ||||
|   font-size: 1em; | ||||
|   max-width: 3em; | ||||
| 
 | ||||
|   color: transparent; | ||||
|   text-shadow: 0 0 0 white; | ||||
|   border: none; | ||||
|   box-shadow:0px 0px 0px 2px var(--accent-darkest) inset; | ||||
|    | ||||
|   transform-style: preserve-3d; | ||||
|   transition: cubic-bezier(0, 0, 0.58, 1), cubic-bezier(0, 0, 0.58, 1); | ||||
|   transition-duration: 150ms; | ||||
| } | ||||
| 
 | ||||
| #options-toggle #options-icon::before { | ||||
|   content: ""; | ||||
| 
 | ||||
|   position: absolute; | ||||
|    | ||||
|   width: 100%; | ||||
|   height: 100%; | ||||
|   top: 0; | ||||
|   left: 0; | ||||
|   right: 0; | ||||
|   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; | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue