Changed around line 1
- let staticNoise = document.querySelector(".staticNoise")
- let powerScreen = document.querySelector(".powerScreen")
- const lodash = _
+ let staticNoise = document.querySelector(".staticNoise");
+ let powerScreen = document.querySelector(".powerScreen");
+ const lodash = _;
- const defaultJam = "all"
+ const defaultJam = "all";
- [platform, channeltitle.replace(/\s+/g, "")].join(".")
+ [platform, channeltitle.replace(/\s+/g, "")].join(".");
- this.isRemoteVisible = true // Add this line near the top
+ this.isRemoteVisible = true; // Add this line near the top
Changed around line 18: class Togger {
- )
- this.jamNames.sort()
- const params = new URLSearchParams(window.location.search)
+ );
+ this.jamNames.sort();
+ const params = new URLSearchParams(window.location.search);
- defaultJam
+ defaultJam;
- if (startJam === "coding")
- startJam = "code"
+ if (startJam === "coding") startJam = "code";
- this.jamIndexes = {}
+ this.jamIndexes = {};
- this.jamIndexes[name] = 0
- })
+ this.jamIndexes[name] = 0;
+ });
- this.loadStreams(startJam)
- if (params.get("shuffle")) this.shuffle()
- this.currentIndex = this.getInitialIndex()
+ this.loadStreams(startJam);
+ if (params.get("shuffle")) this.shuffle();
+ this.currentIndex = this.getInitialIndex();
- this.jamIndexes[this.jamName] = this.currentIndex
+ this.jamIndexes[this.jamName] = this.currentIndex;
- this.isPoweredOn = true
- this.isMuted = true
- this.bindKeyboardControls()
- this.createChatOverlay()
+ this.isPoweredOn = true;
+ this.isMuted = true;
+ this.bindKeyboardControls();
+ this.createChatOverlay();
- const overlay = document.createElement("div")
- overlay.className = "chat-overlay"
+ const overlay = document.createElement("div");
+ overlay.className = "chat-overlay";
Changed around line 63: class Togger {
- `
+ `;
- const header = document.createElement("div")
+ const header = document.createElement("div");
Changed around line 76: class Togger {
- `
- header.textContent = "Live Chat"
+ `;
+ header.textContent = "Live Chat";
- const closeButton = document.createElement("button")
+ const closeButton = document.createElement("button");
Changed around line 91: class Togger {
- `
- closeButton.textContent = "×"
- closeButton.addEventListener("click", () => this.toggleChat())
+ `;
+ closeButton.textContent = "×";
+ closeButton.addEventListener("click", () => this.toggleChat());
- const chatFrame = document.createElement("iframe")
+ const chatFrame = document.createElement("iframe");
- `
+ `;
- header.appendChild(closeButton)
- overlay.appendChild(header)
- overlay.appendChild(chatFrame)
- document.body.appendChild(overlay)
+ header.appendChild(closeButton);
+ overlay.appendChild(header);
+ overlay.appendChild(chatFrame);
+ document.body.appendChild(overlay);
- this.chatOverlay = overlay
- this.chatFrame = chatFrame
- this.addRemoteControl()
+ this.chatOverlay = overlay;
+ this.chatFrame = chatFrame;
+ this.addRemoteControl();
- this.isChatVisible = !this.isChatVisible
- const indicator = document.querySelector(".indicator")
+ this.isChatVisible = !this.isChatVisible;
+ const indicator = document.querySelector(".indicator");
- this.chatOverlay.style.display = "block"
- this.updateChatUrl()
- indicator.style.right = "420px" // 400px chat width + 20px original padding
+ this.chatOverlay.style.display = "block";
+ this.updateChatUrl();
+ indicator.style.right = "420px"; // 400px chat width + 20px original padding
- this.chatOverlay.style.display = "none"
- indicator.style.right = "20px"
+ this.chatOverlay.style.display = "none";
+ indicator.style.right = "20px";
- this.resizePlayer()
- this.showIndicator(this.isChatVisible ? "Chat: ON" : "Chat: OFF")
+ this.resizePlayer();
+ this.showIndicator(this.isChatVisible ? "Chat: ON" : "Chat: OFF");
Changed around line 136: class Togger {
- window.location.hostname
+ window.location.hostname;
- this.isRemoteVisible = !this.isRemoteVisible
- const remote = document.querySelector(".remote-control")
+ this.isRemoteVisible = !this.isRemoteVisible;
+ const remote = document.querySelector(".remote-control");
- remote.style.display = this.isRemoteVisible ? "block" : "none"
+ remote.style.display = this.isRemoteVisible ? "block" : "none";
- this.showIndicator(this.isRemoteVisible ? "Remote: ON" : "Remote: OFF")
+ this.showIndicator(this.isRemoteVisible ? "Remote: ON" : "Remote: OFF");
- const params = new URLSearchParams(window.location.search)
- const customVideoId = params.get("v")
- if (!customVideoId) return ""
+ const params = new URLSearchParams(window.location.search);
+ const customVideoId = params.get("v");
+ if (!customVideoId) return "";
Changed around line 162: class Togger {
- })
+ });
- _channels
+ _channels;
- if (this._channels) return this._channels
- this._channels = sorted.slice()
+ if (this._channels) return this._channels;
+ this._channels = sorted.slice();
- channel.jams += " all"
- })
- this.maybeAddCustomChannel()
- return this._channels
+ channel.jams += " all";
+ });
+ this.maybeAddCustomChannel();
+ return this._channels;
- return this.jamNames.indexOf(this.jamName)
+ return this.jamNames.indexOf(this.jamName);
- this.jamIndexes[this.jamName] = this.currentIndex
+ this.jamIndexes[this.jamName] = this.currentIndex;
- const { jamNames, jamIndex } = this
- const jamName = jamNames[(jamIndex + 1) % jamNames.length]
- this.loadStreams(jamName)
+ const { jamNames, jamIndex } = this;
+ const jamName = jamNames[(jamIndex + 1) % jamNames.length];
+ this.loadStreams(jamName);
- this.currentIndex = this.jamIndexes[jamName]
- this.playStream()
+ this.currentIndex = this.jamIndexes[jamName];
+ this.playStream();
- this.jamIndexes[this.jamName] = this.currentIndex
+ this.jamIndexes[this.jamName] = this.currentIndex;
- const { jamNames, jamIndex } = this
+ const { jamNames, jamIndex } = this;
- jamNames[
- (jamIndex - 1 + jamNames.length) % jamNames.length
- ]
- this.loadStreams(jamName)
+ jamNames[(jamIndex - 1 + jamNames.length) % jamNames.length];
+ this.loadStreams(jamName);
- this.currentIndex = this.jamIndexes[jamName]
- this.playStream()
+ this.currentIndex = this.jamIndexes[jamName];
+ this.playStream();
- const { jamNames } = this
- if (!jamNames.includes(jamName)) jamName = defaultJam
- this.jamName = jamName
- return this.channels.filter((c) => c.jams?.includes(jamName))
+ const { jamNames } = this;
+ if (!jamNames.includes(jamName)) jamName = defaultJam;
+ this.jamName = jamName;
+ return this.channels.filter((c) => c.jams?.includes(jamName));
- let streams = this.getJam(jamName)
+ let streams = this.getJam(jamName);
- const channeltitle = item.channeltitle
- const platform = "youtube"
+ const channeltitle = item.channeltitle;
+ const platform = "youtube";
- }
- })
+ };
+ });
- )
+ );
- this.streams = lodash.sortBy(this.streams, "status")
+ this.streams = lodash.sortBy(this.streams, "status");
- )
+ );
- this.streams = streams
+ this.streams = streams;
- const params = new URLSearchParams(window.location.search)
- const deepLink = params.get("channel") || params.get("c")
- if (!deepLink) return 0
+ const params = new URLSearchParams(window.location.search);
+ const deepLink = params.get("channel") || params.get("c");
+ if (!deepLink) return 0;
- const hit = this.streams.findIndex((stream) => stream.deepLink === deepLink)
- return hit > -1 ? hit : 0
+ const hit = this.streams.findIndex(
+ (stream) => stream.deepLink === deepLink,
+ );
+ return hit > -1 ? hit : 0;
- this.player = player
+ this.player = player;
- setTimeout(() => this.showVolumeIndicator(), 1000)
+ setTimeout(() => this.showVolumeIndicator(), 1000);
- window.addEventListener("resize", () => this.resizePlayer(), true)
+ window.addEventListener("resize", () => this.resizePlayer(), true);
- this.streams = lodash.shuffle(this.streams)
+ this.streams = lodash.shuffle(this.streams);
- this.previousChannel()
- break
+ this.previousChannel();
+ break;
- this.nextChannel()
- break
+ this.nextChannel();
+ break;
- this.nextJam()
- break
+ this.nextJam();
+ break;
- this.previousJam()
- break
+ this.previousJam();
+ break;
- )
- break
+ );
+ break;
- this.toggleMute()
- break
+ this.toggleMute();
+ break;
- this.togglePower()
- break
+ this.togglePower();
+ break;
- this.toggleChat()
- break
+ this.toggleChat();
+ break;
- this.decreaseVolume()
- break
+ this.decreaseVolume();
+ break;
- this.increaseVolume()
- break
+ this.increaseVolume();
+ break;
- this.toggleRemote()
- break
+ this.toggleRemote();
+ break;
- this.shuffle()
- this.nextChannel()
- break
+ this.shuffle();
+ this.nextChannel();
+ break;
- })
+ });
- return this.streams[this.currentIndex]
+ return this.streams[this.currentIndex];
- this.currentIndex = (this.currentIndex + 1) % this.streams.length
- if (this.currentChannel.status === "removed") return this.nextChannel()
- this.playStream()
+ this.currentIndex = (this.currentIndex + 1) % this.streams.length;
+ if (this.currentChannel.status === "removed") return this.nextChannel();
+ this.playStream();
- (this.currentIndex - 1 + this.streams.length) % this.streams.length
- if (this.currentChannel.status === "removed") return this.previousChannel()
- this.playStream()
+ (this.currentIndex - 1 + this.streams.length) % this.streams.length;
+ if (this.currentChannel.status === "removed") return this.previousChannel();
+ this.playStream();
- volume = 100
+ volume = 100;
- const { volume, isMuted } = this
- this.showIndicator(isMuted ? "MUTED" : `Volume: ${volume}`)
+ const { volume, isMuted } = this;
+ this.showIndicator(isMuted ? "MUTED" : `Volume: ${volume}`);
- const indicator = document.querySelector(".indicator")
- indicator.textContent = message
- indicator.style.display = "block"
+ const indicator = document.querySelector(".indicator");
+ indicator.textContent = message;
+ indicator.style.display = "block";
- if (this.indicatorTimeout) clearTimeout(this.indicatorTimeout)
+ if (this.indicatorTimeout) clearTimeout(this.indicatorTimeout);
- indicator.style.display = "none"
- }, 3000)
+ indicator.style.display = "none";
+ }, 3000);
- let delta = 20
- if (this.volume === 0) delta = 1
- if (this.volume === 1) delta = 4
- if (this.volume === 5) delta = 5
- if (this.volume === 10) delta = 10
- this.volume = Math.min(100, this.volume + delta)
- this.player.setVolume(this.volume)
- this.showVolumeIndicator()
+ let delta = 20;
+ if (this.volume === 0) delta = 1;
+ if (this.volume === 1) delta = 4;
+ if (this.volume === 5) delta = 5;
+ if (this.volume === 10) delta = 10;
+ this.volume = Math.min(100, this.volume + delta);
+ this.player.setVolume(this.volume);
+ this.showVolumeIndicator();
- let delta = 20
- if (this.volume === 20) delta = 10
- if (this.volume === 10) delta = 5
- if (this.volume === 5) delta = 4
- this.volume = Math.min(100, Math.max(0, this.volume - delta))
- this.player.setVolume(this.volume)
- this.showVolumeIndicator()
+ let delta = 20;
+ if (this.volume === 20) delta = 10;
+ if (this.volume === 10) delta = 5;
+ if (this.volume === 5) delta = 4;
+ this.volume = Math.min(100, Math.max(0, this.volume - delta));
+ this.player.setVolume(this.volume);
+ this.showVolumeIndicator();
- this.isMuted = false
- this.player.unMute()
+ this.isMuted = false;
+ this.player.unMute();
- this.isMuted = true
- this.player.mute()
+ this.isMuted = true;
+ this.player.mute();
- if (this.isMuted) this.unmute()
- else this.mute()
- this.showVolumeIndicator()
+ if (this.isMuted) this.unmute();
+ else this.mute();
+ this.showVolumeIndicator();
- if (this.isPoweredOn) this.powerOff()
- else this.powerOn()
+ if (this.isPoweredOn) this.powerOff();
+ else this.powerOn();
- if (!this.isPoweredOn) return
- this.didLoad = false
+ if (!this.isPoweredOn) return;
+ this.didLoad = false;
- const current = this.currentChannel
- this.updateChannelTitle()
+ const current = this.currentChannel;
+ this.updateChannelTitle();
- this.player.mute()
- this.player.loadVideoById(current.streamLink)
- this.player.setVolume(this.volume)
- this.player.setPlaybackRate(1)
- this.updateChatUrl()
+ this.player.mute();
+ this.player.loadVideoById(current.streamLink);
+ this.player.setVolume(this.volume);
+ this.player.setPlaybackRate(1);
+ this.updateChatUrl();
- this.updateUrl()
+ this.updateUrl();
- this.startUpdatingUrl = true
+ this.startUpdatingUrl = true;
- const params = new URLSearchParams(window.location.search)
+ const params = new URLSearchParams(window.location.search);
- params.delete("c")
- params.delete("p")
- params.set("channel", this.currentChannel.deepLink)
- params.set("jam", this.jamName)
+ params.delete("c");
+ params.delete("p");
+ params.set("channel", this.currentChannel.deepLink);
+ params.set("jam", this.jamName);
- window.history.replaceState({}, "", `?${params.toString()}`)
+ window.history.replaceState({}, "", `?${params.toString()}`);
- const current = this.streams[this.currentIndex]
- let liveIndicator = "↺"
+ const current = this.streams[this.currentIndex];
+ let liveIndicator = "↺";
- : '- OFF-AIR'
+ : '- OFF-AIR';
- const url = `https://www.youtube.com/watch?v=${current.neweststream}`
- const title = [this.jamName, current.channeltitle].join(".")
+ const url = `https://www.youtube.com/watch?v=${current.neweststream}`;
+ const title = [this.jamName, current.channeltitle].join(".");
Changed around line 450: class Togger {
- }
+ };
- .join(" ")
+ .join(" ");
- `
- this.showChannel()
+ `;
+ this.showChannel();
- const indicator = document.querySelector(".channelName")
- indicator.style.opacity = "1"
+ const indicator = document.querySelector(".channelName");
+ indicator.style.opacity = "1";
- if (this.channelTimeout) clearTimeout(this.channelTimeout)
+ if (this.channelTimeout) clearTimeout(this.channelTimeout);
- indicator.style.opacity = "0"
- }, 5000)
+ indicator.style.opacity = "0";
+ }, 5000);
- let p = document.querySelector("#player")
- p.style.top = -window.innerHeight * 0.5 + "px"
+ let p = document.querySelector("#player");
+ p.style.top = -window.innerHeight * 0.5 + "px";
- : window.innerWidth
+ : window.innerWidth;
- "px"
+ "px";
- )
+ );
- this.isPoweredOn = true
- if (powerScreen) powerScreen.style.display = "none"
- this.playStream()
+ this.isPoweredOn = true;
+ if (powerScreen) powerScreen.style.display = "none";
+ this.playStream();
- this.isPoweredOn = false
- if (powerScreen) powerScreen.style.display = "block"
- this.player.stopVideo()
- staticNoise.style.opacity = 1
+ this.isPoweredOn = false;
+ if (powerScreen) powerScreen.style.display = "block";
+ this.player.stopVideo();
+ staticNoise.style.opacity = 1;
- const current = this.streams[this.currentIndex]
+ const current = this.streams[this.currentIndex];
- return this.player.playerInfo.videoData.isLive
+ return this.player.playerInfo.videoData.isLive;
- const now = new Date()
- const totalMinutes = now.getUTCHours() * 60 + now.getUTCMinutes()
- const totalSeconds = totalMinutes * 60 + now.getUTCSeconds()
+ const now = new Date();
+ const totalMinutes = now.getUTCHours() * 60 + now.getUTCMinutes();
+ const totalSeconds = totalMinutes * 60 + now.getUTCSeconds();
- return totalSeconds % duration
+ return totalSeconds % duration;
- return totalSeconds
+ return totalSeconds;
- if (!this.isPoweredOn) return
+ if (!this.isPoweredOn) return;
- staticNoise.style.opacity = 1
+ staticNoise.style.opacity = 1;
Changed around line 544: class Togger {
- const videoData = this.player.getVideoData()
- const isLive = this.checkIfLive()
- if (this.didLoad || isLive) staticNoise.style.opacity = 0
+ const videoData = this.player.getVideoData();
+ const isLive = this.checkIfLive();
+ if (this.didLoad || isLive) staticNoise.style.opacity = 0;
- const duration = this.player.getDuration()
- const seekPosition = this.getTimeBasedSeekPosition(duration)
- this.player.seekTo(seekPosition, true)
+ const duration = this.player.getDuration();
+ const seekPosition = this.getTimeBasedSeekPosition(duration);
+ this.player.seekTo(seekPosition, true);
- this.player.unMute()
+ this.player.unMute();
- this.didLoad = true
+ this.didLoad = true;
- this.reportStatus("off")
+ this.reportStatus("off");
- this.reportStatus("live")
+ this.reportStatus("live");
- this.updateChannelTitle(isLive)
+ this.updateChannelTitle(isLive);
Changed around line 578: class Togger {
- this.currentChannel.status = value
- const filename = `channels/${this.currentChannel.id}.scroll`
+ this.currentChannel.status = value;
+ const filename = `channels/${this.currentChannel.id}.scroll`;
Changed around line 588: class Togger {
- )
+ );
- throw new Error(`HTTP error! status: ${response.status}`)
+ throw new Error(`HTTP error! status: ${response.status}`);
- console.error("Error reporting channel offline:", error)
+ console.error("Error reporting channel offline:", error);
- this.playStream() // Start playing as soon as the player is ready
- document.querySelector(".mute").focus()
+ this.playStream(); // Start playing as soon as the player is ready
+ document.querySelector(".mute").focus();
- const existingRemote = document.querySelector(".remote-control")
+ const existingRemote = document.querySelector(".remote-control");
- existingRemote.remove()
+ existingRemote.remove();
- const remote = document.createElement("div")
- remote.className = "remote-control"
- remote.style.display = this.isRemoteVisible ? "block" : "none"
+ const remote = document.createElement("div");
+ remote.className = "remote-control";
+ remote.style.display = this.isRemoteVisible ? "block" : "none";
- const dragHandle = document.createElement("div")
- dragHandle.className = "drag-handle"
- remote.appendChild(dragHandle)
+ const dragHandle = document.createElement("div");
+ dragHandle.className = "drag-handle";
+ remote.appendChild(dragHandle);
- const irEmitter = document.createElement("div")
- irEmitter.className = "ir-emitter"
- remote.appendChild(irEmitter)
+ const irEmitter = document.createElement("div");
+ irEmitter.className = "ir-emitter";
+ remote.appendChild(irEmitter);
- const button = document.createElement("button")
- const classes = []
- if (options.isMute) classes.push("mute")
- button.className = classes.join(" ")
- button.textContent = text
+ const button = document.createElement("button");
+ const classes = [];
+ if (options.isMute) classes.push("mute");
+ button.className = classes.join(" ");
+ button.textContent = text;
- button.style.transform = "scale(0.95)"
- setTimeout(() => (button.style.transform = ""), 100)
- document.dispatchEvent(new KeyboardEvent("keydown", { key }))
- })
+ button.style.transform = "scale(0.95)";
+ setTimeout(() => (button.style.transform = ""), 100);
+ document.dispatchEvent(new KeyboardEvent("keydown", { key }));
+ });
- return button
+ return button;
- const row = document.createElement("div")
- row.className = "button-row"
- buttons.forEach((button) => row.appendChild(button))
- return row
+ const row = document.createElement("div");
+ row.className = "button-row";
+ buttons.forEach((button) => row.appendChild(button));
+ return row;
- ])
- remote.appendChild(muteRow)
-
- const channelRow = createButtonRow([
- createButton("CH-", "ArrowLeft"),
- createButton("CH+", "ArrowRight"),
- ])
- remote.appendChild(channelRow)
+ ]);
+ remote.appendChild(muteRow);
- ])
- remote.appendChild(jamRow)
+ ]);
+ remote.appendChild(jamRow);
+
+ const channelRow = createButtonRow([
+ createButton("CH-", "ArrowLeft"),
+ createButton("CH+", "ArrowRight"),
+ ]);
+ remote.appendChild(channelRow);
- ])
- remote.appendChild(volumeControlRow)
+ ]);
+ remote.appendChild(volumeControlRow);
- const chatRow = createButtonRow([createButton("CHAT", "c")])
- remote.appendChild(chatRow)
+ const chatRow = createButtonRow([createButton("CHAT", "c")]);
+ remote.appendChild(chatRow);
- document.body.appendChild(remote)
+ document.body.appendChild(remote);
- let isDragging = false
- let currentX, currentY, initialX, initialY
+ let isDragging = false;
+ let currentX, currentY, initialX, initialY;
- yOffset = 0
+ yOffset = 0;
- initialX = e.touches[0].clientX - xOffset
- initialY = e.touches[0].clientY - yOffset
+ initialX = e.touches[0].clientX - xOffset;
+ initialY = e.touches[0].clientY - yOffset;
- initialX = e.clientX - xOffset
- initialY = e.clientY - yOffset
+ initialX = e.clientX - xOffset;
+ initialY = e.clientY - yOffset;
- isDragging = true
+ isDragging = true;
- initialX = currentX
- initialY = currentY
- isDragging = false
+ initialX = currentX;
+ initialY = currentY;
+ isDragging = false;
- e.preventDefault()
+ e.preventDefault();
- currentX = e.touches[0].clientX - initialX
- currentY = e.touches[0].clientY - initialY
+ currentX = e.touches[0].clientX - initialX;
+ currentY = e.touches[0].clientY - initialY;
- currentX = e.clientX - initialX
- currentY = e.clientY - initialY
+ currentX = e.clientX - initialX;
+ currentY = e.clientY - initialY;
- xOffset = currentX
- yOffset = currentY
- remote.style.transform = `translate(${xOffset}px, ${yOffset}px)`
+ xOffset = currentX;
+ yOffset = currentY;
+ remote.style.transform = `translate(${xOffset}px, ${yOffset}px)`;
- remote.addEventListener("touchstart", dragStart, false)
- remote.addEventListener("touchend", dragEnd, false)
- remote.addEventListener("touchmove", drag, false)
- remote.addEventListener("mousedown", dragStart, false)
- document.addEventListener("mouseup", dragEnd, false)
- document.addEventListener("mousemove", drag, false)
+ remote.addEventListener("touchstart", dragStart, false);
+ remote.addEventListener("touchend", dragEnd, false);
+ remote.addEventListener("touchmove", drag, false);
+ remote.addEventListener("mousedown", dragStart, false);
+ document.addEventListener("mouseup", dragEnd, false);
+ document.addEventListener("mousemove", drag, false);
- const togger = new Togger()
+ const togger = new Togger();
Changed around line 752: This event fires if an error occurs in the player. The API will pass an event ob
- 150 – This error is the same as 101. It's just a 101 error in disguise!`)
- console.error(event)
+ 150 – This error is the same as 101. It's just a 101 error in disguise!`);
+ console.error(event);
- togger.reportStatus("removed")
+ togger.reportStatus("removed");
- })
+ });
- togger.setPlayer(player)
- togger.resizePlayer()
- togger.bindToResize()
- window.togger = togger
+ togger.setPlayer(player);
+ togger.resizePlayer();
+ togger.bindToResize();
+ window.togger = togger;
- var scriptUrl = "https://www.youtube.com/iframe_api"
- var tag = document.createElement("script")
- tag.src = scriptUrl
- var firstScriptTag = document.getElementsByTagName("script")[0]
- firstScriptTag.parentNode.insertBefore(tag, firstScriptTag)
+ var scriptUrl = "https://www.youtube.com/iframe_api";
+ var tag = document.createElement("script");
+ tag.src = scriptUrl;
+ var firstScriptTag = document.getElementsByTagName("script")[0];
+ firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);