forked from lavender/watch-party
		
	add /sync command
this command resyncs you with the watch party also added: /help command
This commit is contained in:
		
							parent
							
								
									af4b23e879
								
							
						
					
					
						commit
						ef50f2c4d9
					
				
					 9 changed files with 73 additions and 26 deletions
				
			
		|  | @ -3,7 +3,7 @@ | ||||||
|   <head> |   <head> | ||||||
|     <meta charset="utf-8" /> |     <meta charset="utf-8" /> | ||||||
|     <title>watch party :D</title> |     <title>watch party :D</title> | ||||||
|     <link rel="stylesheet" href="/styles.css?v=8" /> |     <link rel="stylesheet" href="/styles.css?v=9" /> | ||||||
|   </head> |   </head> | ||||||
| 
 | 
 | ||||||
|   <body> |   <body> | ||||||
|  | @ -47,6 +47,6 @@ | ||||||
|       </p> |       </p> | ||||||
|     </div> |     </div> | ||||||
| 
 | 
 | ||||||
|     <script type="module" src="/create.mjs?v=8"></script> |     <script type="module" src="/create.mjs?v=9"></script> | ||||||
|   </body> |   </body> | ||||||
| </html> | </html> | ||||||
|  |  | ||||||
|  | @ -1,4 +1,4 @@ | ||||||
| import { setupCreateSessionForm } from "./lib/create-session.mjs?v=8"; | import { setupCreateSessionForm } from "./lib/create-session.mjs?v=9"; | ||||||
| 
 | 
 | ||||||
| const main = () => { | const main = () => { | ||||||
|   setupCreateSessionForm(); |   setupCreateSessionForm(); | ||||||
|  |  | ||||||
|  | @ -3,7 +3,7 @@ | ||||||
|   <head> |   <head> | ||||||
|     <meta charset="utf-8" /> |     <meta charset="utf-8" /> | ||||||
|     <title>watch party :D</title> |     <title>watch party :D</title> | ||||||
|     <link rel="stylesheet" href="/styles.css?v=8" /> |     <link rel="stylesheet" href="/styles.css?v=9" /> | ||||||
|   </head> |   </head> | ||||||
| 
 | 
 | ||||||
|   <body> |   <body> | ||||||
|  | @ -53,10 +53,10 @@ | ||||||
|       <div id="viewer-list"></div> |       <div id="viewer-list"></div> | ||||||
|       <div id="chatbox"></div> |       <div id="chatbox"></div> | ||||||
|       <form id="chatbox-send"> |       <form id="chatbox-send"> | ||||||
|         <input type="text" placeholder="Message..." /> |         <input type="text" placeholder="Message... (/help for commands)" /> | ||||||
|       </form> |       </form> | ||||||
|     </div> |     </div> | ||||||
| 
 | 
 | ||||||
|     <script type="module" src="/main.mjs?v=8"></script> |     <script type="module" src="/main.mjs?v=9"></script> | ||||||
|   </body> |   </body> | ||||||
| </html> | </html> | ||||||
|  |  | ||||||
|  | @ -1,10 +1,12 @@ | ||||||
|  | import { setDebounce, setVideoTime, setPlaying } from "./watch-session.mjs"; | ||||||
|  | 
 | ||||||
| const setupChatboxEvents = (socket) => { | const setupChatboxEvents = (socket) => { | ||||||
|   // clear events by just reconstructing the form
 |   // clear events by just reconstructing the form
 | ||||||
|   const oldChatForm = document.querySelector("#chatbox-send"); |   const oldChatForm = document.querySelector("#chatbox-send"); | ||||||
|   const chatForm = oldChatForm.cloneNode(true); |   const chatForm = oldChatForm.cloneNode(true); | ||||||
|   oldChatForm.replaceWith(chatForm); |   oldChatForm.replaceWith(chatForm); | ||||||
| 
 | 
 | ||||||
|   chatForm.addEventListener("submit", (e) => { |   chatForm.addEventListener("submit", async (e) => { | ||||||
|     e.preventDefault(); |     e.preventDefault(); | ||||||
| 
 | 
 | ||||||
|     const input = chatForm.querySelector("input"); |     const input = chatForm.querySelector("input"); | ||||||
|  | @ -28,8 +30,35 @@ const setupChatboxEvents = (socket) => { | ||||||
|             ); |             ); | ||||||
|             handled = true; |             handled = true; | ||||||
|             break; |             break; | ||||||
|  |           case "/sync": | ||||||
|  |             const sessionId = window.location.hash.slice(1); | ||||||
|  |             const { current_time_ms, is_playing } = await fetch( | ||||||
|  |               `/sess/${sessionId}` | ||||||
|  |             ).then((r) => r.json()); | ||||||
|  | 
 | ||||||
|  |             setDebounce(); | ||||||
|  |             setPlaying(is_playing); | ||||||
|  |             setVideoTime(current_time_ms); | ||||||
|  | 
 | ||||||
|  |             const syncMessageContent = document.createElement("span"); | ||||||
|  |             syncMessageContent.appendChild( | ||||||
|  |               document.createTextNode("resynced you to ") | ||||||
|  |             ); | ||||||
|  |             syncMessageContent.appendChild( | ||||||
|  |               document.createTextNode(formatTime(current_time_ms)) | ||||||
|  |             ); | ||||||
|  |             printChatMessage("set-time", "/sync", "b57fdc", syncMessageContent); | ||||||
|  |             handled = true; | ||||||
|  |             break; | ||||||
|           case "/help": |           case "/help": | ||||||
|             // TODO: print help in chat
 |             const helpMessageContent = document.createElement("span"); | ||||||
|  |             helpMessageContent.innerHTML = | ||||||
|  |               "Available commands:<br>" + | ||||||
|  |               " <code>/help</code> - display this help message<br>" + | ||||||
|  |               " <code>/ping [message]</code> - ping all viewers<br>" + | ||||||
|  |               " <code>/sync</code> - resyncs you with other viewers"; | ||||||
|  | 
 | ||||||
|  |             printChatMessage("command-message", "/help", "b57fdc", helpMessageContent); | ||||||
|             handled = true; |             handled = true; | ||||||
|             break; |             break; | ||||||
|           default: |           default: | ||||||
|  |  | ||||||
|  | @ -1,4 +1,4 @@ | ||||||
| import { createSession } from "./watch-session.mjs?v=8"; | import { createSession } from "./watch-session.mjs?v=9"; | ||||||
| 
 | 
 | ||||||
| export const setupCreateSessionForm = () => { | export const setupCreateSessionForm = () => { | ||||||
|   const form = document.querySelector("#create-session-form"); |   const form = document.querySelector("#create-session-form"); | ||||||
|  |  | ||||||
|  | @ -1,4 +1,4 @@ | ||||||
| import { joinSession } from "./watch-session.mjs?v=8"; | import { joinSession } from "./watch-session.mjs?v=9"; | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
|  * @param {HTMLInputElement} field |  * @param {HTMLInputElement} field | ||||||
|  |  | ||||||
|  | @ -1,5 +1,5 @@ | ||||||
| import { setupVideo } from "./video.mjs?v=8"; | import { setupVideo } from "./video.mjs?v=9"; | ||||||
| import { setupChat, logEventToChat, updateViewerList } from "./chat.mjs?v=8"; | import { setupChat, logEventToChat, updateViewerList } from "./chat.mjs?v=9"; | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
|  * @param {string} sessionId |  * @param {string} sessionId | ||||||
|  | @ -22,7 +22,7 @@ const createWebSocket = (sessionId, nickname, colour) => { | ||||||
| let outgoingDebounce = false; | let outgoingDebounce = false; | ||||||
| let outgoingDebounceCallbackId = null; | let outgoingDebounceCallbackId = null; | ||||||
| 
 | 
 | ||||||
| const setDebounce = () => { | export const setDebounce = () => { | ||||||
|   outgoingDebounce = true; |   outgoingDebounce = true; | ||||||
| 
 | 
 | ||||||
|   if (outgoingDebounceCallbackId) { |   if (outgoingDebounceCallbackId) { | ||||||
|  | @ -35,19 +35,34 @@ const setDebounce = () => { | ||||||
|   }, 500); |   }, 500); | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | export const setVideoTime = (time, video = null) => { | ||||||
|  |   if (video == null) { | ||||||
|  |     video = document.querySelector("video"); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   const timeSecs = time / 1000.0; | ||||||
|  |   if (Math.abs(video.currentTime - timeSecs) > 0.5) { | ||||||
|  |     video.currentTime = timeSecs; | ||||||
|  |   } | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | export const setPlaying = async (playing, video = null) => { | ||||||
|  |   if (video == null) { | ||||||
|  |     video = document.querySelector("video"); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   if (playing) { | ||||||
|  |     await video.play(); | ||||||
|  |   } else { | ||||||
|  |     video.pause(); | ||||||
|  |   } | ||||||
|  | }; | ||||||
|  | 
 | ||||||
| /** | /** | ||||||
|  * @param {HTMLVideoElement} video |  * @param {HTMLVideoElement} video | ||||||
|  * @param {WebSocket} socket |  * @param {WebSocket} socket | ||||||
|  */ |  */ | ||||||
| const setupIncomingEvents = (video, socket) => { | const setupIncomingEvents = (video, socket) => { | ||||||
|   const setVideoTime = (time) => { |  | ||||||
|     const timeSecs = time / 1000.0; |  | ||||||
| 
 |  | ||||||
|     if (Math.abs(video.currentTime - timeSecs) > 0.5) { |  | ||||||
|       video.currentTime = timeSecs; |  | ||||||
|     } |  | ||||||
|   }; |  | ||||||
| 
 |  | ||||||
|   socket.addEventListener("message", async (messageEvent) => { |   socket.addEventListener("message", async (messageEvent) => { | ||||||
|     try { |     try { | ||||||
|       const event = JSON.parse(messageEvent.data); |       const event = JSON.parse(messageEvent.data); | ||||||
|  | @ -63,12 +78,11 @@ const setupIncomingEvents = (video, socket) => { | ||||||
|               video.pause(); |               video.pause(); | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             setVideoTime(event.data.time); |             setVideoTime(event.data.time, video); | ||||||
| 
 |  | ||||||
|             break; |             break; | ||||||
|           case "SetTime": |           case "SetTime": | ||||||
|             setDebounce(); |             setDebounce(); | ||||||
|             setVideoTime(event.data); |             setVideoTime(event.data, video); | ||||||
|             break; |             break; | ||||||
|           case "UpdateViewerList": |           case "UpdateViewerList": | ||||||
|             updateViewerList(event.data); |             updateViewerList(event.data); | ||||||
|  |  | ||||||
|  | @ -1,4 +1,4 @@ | ||||||
| import { setupJoinSessionForm } from "./lib/join-session.mjs?v=8"; | import { setupJoinSessionForm } from "./lib/join-session.mjs?v=9"; | ||||||
| 
 | 
 | ||||||
| const main = () => { | const main = () => { | ||||||
|   setupJoinSessionForm(); |   setupJoinSessionForm(); | ||||||
|  |  | ||||||
|  | @ -150,9 +150,13 @@ button.small-button { | ||||||
|   font-size: 0.85em; |   font-size: 0.85em; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | .chat-message.command-message{ | ||||||
|  |   font-size: 0.85em; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| .chat-message.set-time > strong, | .chat-message.set-time > strong, | ||||||
| .chat-message.set-playing > strong { | .chat-message.set-playing > strong { | ||||||
|   color: unset; |   color: unset !important; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #chatbox { | #chatbox { | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue