Improve global state handling

This commit is contained in:
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";
import { emojify, findEmojis } from "./emojis.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) {
if (elem.createTextRange) {
@ -191,7 +192,8 @@ const setupChatboxEvents = (socket) => {
handled = true;
break;
case "/join":
joinNewSession(args);
state().sessionId = args;
joinSession();
handled = true;
break;
case "/help":

View file

@ -1,4 +1,5 @@
import { joinSession } from "./watch-session.mjs?v=048af96";
import { state } from "./state.mjs";
/**
* @param {HTMLInputElement} field
@ -80,11 +81,10 @@ export const setupJoinSessionForm = () => {
saveNickname(nickname);
saveColour(colour);
try {
await joinSession(
nickname.value,
sessionId.value,
colour.value.replace(/^#/, "")
);
state().nickname = nickname.value;
state().sessionId = sessionId.value;
state().colour = colour.value.replace(/^#/, "");
await joinSession();
} catch (e) {
alert(e.message);
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(
text,
@ -34,7 +35,8 @@ export async function linkify(
textContent: "Join Session",
className: "chip join-chip",
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
*/
const createVideoElement = (videoUrl, subtitles) => {
const oldVideo = document.getElementById("video");
if (oldVideo) {
oldVideo.remove();
}
const video = document.createElement("video");
video.id = "video";
video.controls = true;
video.autoplay = false;
video.volume = loadVolume();

View file

@ -6,17 +6,18 @@ import {
printChatMessage,
} from "./chat.mjs?v=048af96";
import ReconnectingWebSocket from "./reconnecting-web-socket.mjs";
import { state } from "./state.mjs";
/**
* @param {string} sessionId
* @param {string} nickname
* @returns {ReconnectingWebSocket}
*/
const createWebSocket = (sessionId, nickname, colour) => {
const createWebSocket = () => {
const wsUrl = new URL(
`/sess/${sessionId}/subscribe` +
`?nickname=${encodeURIComponent(nickname)}` +
`&colour=${encodeURIComponent(colour)}`,
`/sess/${state().sessionId}/subscribe` +
`?nickname=${encodeURIComponent(state().nickname)}` +
`&colour=${encodeURIComponent(state().colour)}`,
window.location.href
);
wsUrl.protocol = "ws" + window.location.protocol.slice(4);
@ -167,49 +168,29 @@ const setupOutgoingEvents = (video, socket) => {
});
};
let socket = null;
let video = null;
export const joinNewSession = async (sessionId) => {
export const joinSession = async () => {
if (state().activeSession) {
if (state().activeSession === state().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");
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);
// 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) {
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;
state().activeSession = state().sessionId;
// try { // we are handling errors in the join form.
const genericConnectionError = new Error(
"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;
try {
response = await fetch(`/sess/${sessionId}`);
response = await fetch(`/sess/${state().sessionId}`);
} catch (e) {
console.error(e);
throw genericConnectionError;
@ -233,9 +214,14 @@ export const joinSession = async (nickname, sessionId, colour) => {
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 () => {
video = await setupVideo(
const video = await setupVideo(
video_url,
subtitle_tracks,
current_time_ms,