mirror of
https://github.com/captbaritone/webamp.git
synced 2026-07-24 02:27:37 +00:00
Do a better job of managing http requests
This commit is contained in:
parent
a63bfe5915
commit
c94ca721b5
2 changed files with 85 additions and 6 deletions
40
src/App.js
40
src/App.js
|
|
@ -1,6 +1,7 @@
|
|||
import React from "react";
|
||||
import skins from "./skins.json";
|
||||
import "./App.css";
|
||||
import LoadQueue from "./LoadQueue";
|
||||
|
||||
const hashes = Object.keys(skins);
|
||||
|
||||
|
|
@ -12,14 +13,37 @@ const SKIN_RATIO = SKIN_HEIGHT / SKIN_WIDTH;
|
|||
class Skin extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = { loaded: false };
|
||||
this.state = { loaded: false, load: false };
|
||||
this._controller = new window.AbortController();
|
||||
this._handleLoad = this._handleLoad.bind(this);
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this._dequeue = this.props.queue.enqueue(() => {
|
||||
const signal = this._controller.signal;
|
||||
return fetch(this.props.src, { signal })
|
||||
.then(() => {
|
||||
this.setState({ load: true });
|
||||
})
|
||||
.catch(e => {
|
||||
console.log("aborted?", e);
|
||||
});
|
||||
}, 0);
|
||||
}
|
||||
|
||||
_handleLoad() {
|
||||
this.setState({ loaded: true });
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
if (!this.state.loaded) {
|
||||
this._controller.abort();
|
||||
}
|
||||
if (this._dequeue != null) {
|
||||
this._dequeue();
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div
|
||||
|
|
@ -36,11 +60,13 @@ class Skin extends React.Component {
|
|||
}}
|
||||
>
|
||||
<a href={this.props.href} target="_blank">
|
||||
<img
|
||||
src={this.props.src}
|
||||
className={`screenshot ${this.state.loaded ? "loaded" : ""}`}
|
||||
onLoad={this._handleLoad}
|
||||
/>
|
||||
{this.state.load && (
|
||||
<img
|
||||
src={this.props.src}
|
||||
className={`screenshot ${this.state.loaded ? "loaded" : ""}`}
|
||||
onLoad={this._handleLoad}
|
||||
/>
|
||||
)}
|
||||
</a>
|
||||
</div>
|
||||
);
|
||||
|
|
@ -75,6 +101,7 @@ class App extends React.Component {
|
|||
scrollDirection: null
|
||||
};
|
||||
this._handleScroll();
|
||||
this._queue = new LoadQueue(10);
|
||||
this._handleScroll = this._handleScroll.bind(this);
|
||||
this._handleResize = this._handleResize.bind(this);
|
||||
}
|
||||
|
|
@ -135,6 +162,7 @@ class App extends React.Component {
|
|||
const left = column * columnWidth;
|
||||
skinElements.push(
|
||||
<Skin
|
||||
queue={this._queue}
|
||||
href={`https://webamp.org/?skinUrl=https://s3.amazonaws.com/webamp-uploaded-skins/skins/${hash}.wsz`}
|
||||
src={`https://s3.amazonaws.com/webamp-uploaded-skins/screenshots/${hash}.png`}
|
||||
key={hash}
|
||||
|
|
|
|||
51
src/LoadQueue.js
Normal file
51
src/LoadQueue.js
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
export default class LoadQueue {
|
||||
constructor(size) {
|
||||
this._free = size;
|
||||
this._queue = new Array();
|
||||
}
|
||||
|
||||
_remove(priority, cb) {
|
||||
const priorityQueue = this._queue[priority];
|
||||
if (priorityQueue == null) {
|
||||
return;
|
||||
}
|
||||
priorityQueue.delete(cb);
|
||||
if (priorityQueue.size === 0) {
|
||||
this._queue[priority] = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
enqueue(cb, priority) {
|
||||
if (this._queue[priority] == null) {
|
||||
this._queue[priority] = new Set();
|
||||
}
|
||||
this._queue[priority].add(cb);
|
||||
|
||||
this._run();
|
||||
|
||||
return () => {
|
||||
this._remove(priority, cb);
|
||||
};
|
||||
}
|
||||
_run() {
|
||||
if (this._free === 0) {
|
||||
return;
|
||||
}
|
||||
const priority = this._queue.findIndex(value => Boolean(value));
|
||||
if (priority === -1) {
|
||||
// The queue is empty
|
||||
return;
|
||||
}
|
||||
this._free--;
|
||||
const set = this._queue[priority];
|
||||
const values = set.values();
|
||||
const cb = values.next().value;
|
||||
|
||||
cb().finally(() => {
|
||||
this._free++;
|
||||
this._run();
|
||||
});
|
||||
|
||||
this._remove(priority, cb);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue