Skip to content
This repository has been archived by the owner on Oct 3, 2022. It is now read-only.

V6 #1325

Open
wants to merge 17 commits into
base: v6
Choose a base branch
from
Open

V6 #1325

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 15 additions & 8 deletions client/options/nowPlaying.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,15 +70,22 @@ class Banner {
}

async fetch() {
const response = await fetch(this.api)
if (!response.ok) {
throw Error(await response.text())
}
const data = this.unmarshal(await response.json())
if (!RadioData.is(data)) {
throw Error("Unexpected response")
let response
const defaults = {listeners: 0, song: "ded", streamer: this.url.split('/')[2]}
try {
response = await fetch(this.api)
}catch(err) {
return defaults
}
return data
if (!response.ok) {
return defaults
}

const data = this.unmarshal(await response.json())
if (!RadioData.is(data)) {
return defaults
}
return data
}

async update() {
Expand Down
12 changes: 8 additions & 4 deletions client/options/specs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -150,10 +150,14 @@ export const specs: { [id: string]: OptionSpec } = {
"https://shamiradio.imgoodatth.is/",
"https://shamiradio.imgoodatth.is/status-json.xsl",
({ icestats: { source } }) => {
const [fallback, main] = Array.isArray(source) ? source : [source]
const { listeners, server_name: streamer, title: song = "oh dear, tags aren't set" }
= main?.stream_start ? main : fallback
return { listeners, song, streamer }
if (source === undefined) {
return null
} else {
const [fallback, main] = Array.isArray(source) ? source : [source]
const { listeners, server_name: streamer, title: song = "oh dear, tags aren't set" }
= main?.stream_start ? main : fallback
return { listeners, song, streamer }
}
},
),
},
Expand Down
2 changes: 1 addition & 1 deletion client/posts/posting/drop.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ async function onDrop(e: DragEvent) {
}

let file: File;
if (files.length) {
if (files.length && !url.startsWith('http')) {
file = files[0];
} else if (url) {
// Fetch file from link
Expand Down
71 changes: 60 additions & 11 deletions client/posts/posting/image.ts
Original file line number Diff line number Diff line change
@@ -1,32 +1,81 @@

let consecutiveFailures = 0;
const pendingRetries: Set<HTMLImageElement> = new Set()
const TICK_BASE = 2000;
const TICK_MAX = 60 * 1000;

// Reload image if error
// Handle event if image error
function onImageErr(e: Event) {
const el = (e.target as HTMLImageElement)

if (el.tagName !== "IMG"
|| (el.complete && el.naturalWidth !== 0)
|| el.getAttribute("data-scheduled-retry")) {
|| (el.complete && el.naturalWidth !== 0)) {
return
}

e.stopPropagation()
e.preventDefault()

el.setAttribute("data-scheduled-retry", "1");
setTimeout(() => retry(el), 2000);
// there were no pending entries we need to start a new timer chain
if (pendingRetries.size == 0) {
setTimeout(() => tick(), TICK_BASE)
}

el.dataset.scheduledRetry = "pending"

if (pendingRetries.has(el)) {
consecutiveFailures += 1
// Set maintains insertion-order. We can use that as a queue.
pendingRetries.delete(el)
pendingRetries.add(el)
} else {
pendingRetries.add(el)
}
}

// Retry download
function retry(el: HTMLImageElement) {
if (!document.contains(el) || el.naturalWidth !== 0) {
el.removeAttribute("data-scheduled-retry");
return;
function onImageLoad(e: Event) {
const el = (e.target as HTMLImageElement)

if (el.tagName !== "IMG") {
return
}

if (pendingRetries.has(el)) {
consecutiveFailures = consecutiveFailures / 2
pendingRetries.delete(el)
delete el.dataset.scheduledRetry
}
}


function tick() {
for(let el of pendingRetries) {
// one reload at a time, to avoid hammering the server
if (el.dataset.scheduledRetry === "active") {
break
}
if (el.dataset.scheduledRetry === "pending") {
el.dataset.scheduledRetry = "active"
el.src = el.src
break
}
// skip detached dom nodes and completed images
if (!document.contains(el)
|| (el.complete && el.naturalWidth !== 0)) {
pendingRetries.delete(el)
}
}

if (pendingRetries.size > 0) {
// slow down refreshing if we're experiencing failures
let delay = Math.min(TICK_MAX, TICK_BASE * Math.pow(2, consecutiveFailures))
setTimeout(() => tick(), delay)
}
el.src = el.src;
setTimeout(() => retry(el), 2000);
}

// Bind listeners
export default () => {
document.addEventListener("error", onImageErr, true)
document.addEventListener("load", onImageLoad, true)
}
22 changes: 21 additions & 1 deletion client/ui/keyboard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,21 @@ function handleShortcut(event: KeyboardEvent) {
case "ArrowRight":
navigatePost(false)
break
case "Home":
location.hash = "#top";
break
case "End":
location.hash = "#bottom";
break
case "Insert":
insertMascot();
break
default:
caught = false
}
}

if (event.altKey && !altGr) {
if (event.altKey && (!altGr || navigator.platform == "MacIntel")) {
caught = true

switch (event.which) {
Expand Down Expand Up @@ -116,3 +125,14 @@ function navigatePost(reverse: boolean) {
window.location.hash = current.id
}
}

function insertMascot() {
let mascot = document.getElementById("mascot-image");
if (mascot) {

let img = <HTMLElement>mascot.cloneNode();
img.style.top = window.innerHeight * Math.random() + 'px';
img.style.left = window.innerWidth * Math.random() + 'px';
document.body.appendChild(img);
}
}
1 change: 1 addition & 0 deletions docs/nginx.conf
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ server {
client_body_timeout 600s;
proxy_read_timeout 36000s;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $host;

# WebSockets support
proxy_http_version 1.1;
Expand Down
4 changes: 4 additions & 0 deletions less/base.less
Original file line number Diff line number Diff line change
Expand Up @@ -367,3 +367,7 @@ iframe[src^="https://www.youtube"] {
font-size: 120%;
}
}
@supports (-moz-appearance:none) {
#text-input { overflow: visible ;}
}