Improve global state handling

remotes/1694359591236046747/main
maia arson crimew 2022-03-30 15:02:08 +02:00
parent 9a2ac1c432
commit 40b20b2157
6 changed files with 51 additions and 49 deletions

View File

@ -5,7 +5,8 @@ import {
} from "./watch-session.mjs?v=048af96"; } from "./watch-session.mjs?v=048af96";
import { emojify, findEmojis } from "./emojis.mjs?v=048af96"; import { emojify, findEmojis } from "./emojis.mjs?v=048af96";
import { linkify } from "./links.mjs?v=048af96"; import { linkify } from "./links.mjs?v=048af96";
import { joinNewSession } from "./watch-session.mjs?v=048af96"; import { joinSession } from "./watch-session.mjs?v=048af96";
import { state } from "./state.mjs";
function setCaretPosition(elem, caretPos) { function setCaretPosition(elem, caretPos) {
if (elem.createTextRange) { if (elem.createTextRange) {
@ -191,7 +192,8 @@ const setupChatboxEvents = (socket) => {
handled = true; handled = true;
break; break;
case "/join": case "/join":
joinNewSession(args); state().sessionId = args;
joinSession();
handled = true; handled = true;
break; break;
case "/help": case "/help":

View File

@ -1,4 +1,5 @@
import { joinSession } from "./watch-session.mjs?v=048af96"; import { joinSession } from "./watch-session.mjs?v=048af96";
import { state } from "./state.mjs";
/** /**
* @param {HTMLInputElement} field * @param {HTMLInputElement} field
@ -80,11 +81,10 @@ export const setupJoinSessionForm = () => {
saveNickname(nickname); saveNickname(nickname);
saveColour(colour); saveColour(colour);
try { try {
await joinSession( state().nickname = nickname.value;
nickname.value, state().sessionId = sessionId.value;
sessionId.value, state().colour = colour.value.replace(/^#/, "");
colour.value.replace(/^#/, "") await joinSession();
);
} catch (e) { } catch (e) {
alert(e.message); alert(e.message);
button.disabled = false; button.disabled = false;

View File

@ -1,4 +1,5 @@
import { joinNewSession } from "./watch-session.mjs?v=048af96"; import { joinSession } from "./watch-session.mjs?v=048af96";
import { state } from "./state.mjs";
export async function linkify( export async function linkify(
text, text,
@ -34,7 +35,8 @@ export async function linkify(
textContent: "Join Session", textContent: "Join Session",
className: "chip join-chip", className: "chip join-chip",
onclick: () => { onclick: () => {
joinNewSession(url.hash.substring(1)); state().sessionId = url.hash.substring(1);
joinSession();
}, },
}) })
); );

7
frontend/lib/state.mjs Normal file
View File

@ -0,0 +1,7 @@
let instance = null;
export const state = () => {
if (!instance) {
instance = {};
}
return instance;
};

View File

@ -51,7 +51,12 @@ const saveCaptionsTrack = (track) => {
* @param {{name: string, url: string}[]} subtitles * @param {{name: string, url: string}[]} subtitles
*/ */
const createVideoElement = (videoUrl, subtitles) => { const createVideoElement = (videoUrl, subtitles) => {
const oldVideo = document.getElementById("video");
if (oldVideo) {
oldVideo.remove();
}
const video = document.createElement("video"); const video = document.createElement("video");
video.id = "video";
video.controls = true; video.controls = true;
video.autoplay = false; video.autoplay = false;
video.volume = loadVolume(); video.volume = loadVolume();

View File

@ -6,17 +6,18 @@ import {
printChatMessage, printChatMessage,
} from "./chat.mjs?v=048af96"; } from "./chat.mjs?v=048af96";
import ReconnectingWebSocket from "./reconnecting-web-socket.mjs"; import ReconnectingWebSocket from "./reconnecting-web-socket.mjs";
import { state } from "./state.mjs";
/** /**
* @param {string} sessionId * @param {string} sessionId
* @param {string} nickname * @param {string} nickname
* @returns {ReconnectingWebSocket} * @returns {ReconnectingWebSocket}
*/ */
const createWebSocket = (sessionId, nickname, colour) => { const createWebSocket = () => {
const wsUrl = new URL( const wsUrl = new URL(
`/sess/${sessionId}/subscribe` + `/sess/${state().sessionId}/subscribe` +
`?nickname=${encodeURIComponent(nickname)}` + `?nickname=${encodeURIComponent(state().nickname)}` +
`&colour=${encodeURIComponent(colour)}`, `&colour=${encodeURIComponent(state().colour)}`,
window.location.href window.location.href
); );
wsUrl.protocol = "ws" + window.location.protocol.slice(4); wsUrl.protocol = "ws" + window.location.protocol.slice(4);
@ -167,49 +168,29 @@ const setupOutgoingEvents = (video, socket) => {
}); });
}; };
let socket = null; export const joinSession = async () => {
let video = null; if (state().activeSession) {
if (state().activeSession === state().sessionId) {
export const joinNewSession = async (sessionId) => { // we are already in this session, dont rejoin
return;
}
// we are joining a new session from an existing session
const messageContent = document.createElement("span"); const messageContent = document.createElement("span");
messageContent.appendChild(document.createTextNode("joining new session ")); messageContent.appendChild(document.createTextNode("joining new session "));
messageContent.appendChild(document.createTextNode(sessionId)); messageContent.appendChild(document.createTextNode(state().sessionId));
printChatMessage("join-session", "watch-party", "#fffff", messageContent); printChatMessage("join-session", "watch-party", "#fffff", messageContent);
// clean up previous session
// TODO: this most likely isnt properly working yet when using the /join command to join a new session
if (socket != null) {
socket.close();
socket = null;
} }
if (video != null) { state().activeSession = state().sessionId;
video.remove();
video = null;
}
joinSession(window.nickname, sessionId, sColour);
};
/**
* @param {string} nickname
* @param {string} sessionId
* @param {string} colour
*/
export const joinSession = async (nickname, sessionId, colour) => {
// TODO: we are getting to a point with our features where some kind of
// state store for the various info that is needed in a lot of places would probably make sense
window.nickname = nickname;
window.colour = colour;
// try { // we are handling errors in the join form. // try { // we are handling errors in the join form.
const genericConnectionError = new Error( const genericConnectionError = new Error(
"There was an issue getting the session information." "There was an issue getting the session information."
); );
window.location.hash = sessionId; window.location.hash = state().sessionId;
let response, video_url, subtitle_tracks, current_time_ms, is_playing; let response, video_url, subtitle_tracks, current_time_ms, is_playing;
try { try {
response = await fetch(`/sess/${sessionId}`); response = await fetch(`/sess/${state().sessionId}`);
} catch (e) { } catch (e) {
console.error(e); console.error(e);
throw genericConnectionError; throw genericConnectionError;
@ -233,9 +214,14 @@ export const joinSession = async (nickname, sessionId, colour) => {
throw genericConnectionError; throw genericConnectionError;
} }
socket = createWebSocket(sessionId, nickname, colour); if (state().socket) {
state().socket.close();
state().socket = null;
}
const socket = createWebSocket();
state().socket = socket;
socket.addEventListener("open", async () => { socket.addEventListener("open", async () => {
video = await setupVideo( const video = await setupVideo(
video_url, video_url,
subtitle_tracks, subtitle_tracks,
current_time_ms, current_time_ms,