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="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,5 +1,8 @@ | ||||||
| export const pling = () => { | 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 duration = 0.22; | ||||||
|   const fadeDuration = 0.1; |   const fadeDuration = 0.1; | ||||||
|   const secondBeepOffset = 0.05; |   const secondBeepOffset = 0.05; | ||||||
|  | @ -77,4 +80,3 @@ export const pling = () => { | ||||||
|   thirdBeep.start(ctx.currentTime + thirdBeepOffset); |   thirdBeep.start(ctx.currentTime + thirdBeepOffset); | ||||||
|   thirdBeep.stop(ctx.currentTime + (thirdBeepOffset + duration)); |   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") { | ||||||
|  |  | ||||||
|  | @ -8,6 +8,8 @@ | ||||||
|   --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; | ||||||
|  |   --accent-darker: rgb(95, 37, 136); /*50% darker*/ | ||||||
|  |   --accent-darkest: rgb(47, 19, 68); /*75% darker*/ | ||||||
|   --fg: rgb(var(--fg-rgb)); |   --fg: rgb(var(--fg-rgb)); | ||||||
|   --bg: rgb(var(--bg-rgb)); |   --bg: rgb(var(--bg-rgb)); | ||||||
|   --default-user-color: rgb(126, 208, 255); |   --default-user-color: rgb(126, 208, 255); | ||||||
|  | @ -279,7 +281,6 @@ button.small-button { | ||||||
| 
 | 
 | ||||||
| #chatbox-send { | #chatbox-send { | ||||||
|   padding: 0 1em; |   padding: 0 1em; | ||||||
|   padding-bottom: 0.5em; |  | ||||||
|   position: relative; |   position: relative; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -359,6 +360,73 @@ button.small-button { | ||||||
|   cursor: pointer; |   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 { | input[type="color"]::-moz-color-swatch { | ||||||
|   border: none; |   border: none; | ||||||
|   margin: 0; |   margin: 0; | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue