|
|
@ -12,45 +12,46 @@ const RANDOM_WALLPAPER_URL = `https://source.unsplash.com/collection/${WALLPAPER
|
|
|
|
const largerImage = url => url.replace(/w=\d+/, 'w=1920').replace(/&h=\d+/, '')
|
|
|
|
const largerImage = url => url.replace(/w=\d+/, 'w=1920').replace(/&h=\d+/, '')
|
|
|
|
const smallerImage = url => url.replace(/w=\d+/, 'w=240')
|
|
|
|
const smallerImage = url => url.replace(/w=\d+/, 'w=240')
|
|
|
|
|
|
|
|
|
|
|
|
const imageUrls = {}
|
|
|
|
|
|
|
|
let cache = []
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
async function getImage() {
|
|
|
|
|
|
|
|
// circumvent browser caching
|
|
|
|
|
|
|
|
const sig = Math.floor(Math.random() * RAND_RANGE)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const res = await axios.get(`${RANDOM_WALLPAPER_URL}?sig=${sig}`, { responseType: 'blob' })
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// image already in cache?
|
|
|
|
|
|
|
|
if (imageUrls[res.request.responseURL]) return
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
imageUrls[res.request.responseURL] = true
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
|
|
|
url: res.request.responseURL,
|
|
|
|
|
|
|
|
dataURL: await fileToDataURL(res.data)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
export default class extends React.Component {
|
|
|
|
export default class extends React.Component {
|
|
|
|
constructor() {
|
|
|
|
constructor() {
|
|
|
|
super()
|
|
|
|
super()
|
|
|
|
this.state = { cacheIndex: 0, loading: false }
|
|
|
|
this.state = { cacheIndex: 0, loading: false }
|
|
|
|
this.selectImage = this.selectImage.bind(this)
|
|
|
|
this.selectImage = this.selectImage.bind(this)
|
|
|
|
this.updateCache = this.updateCache.bind(this)
|
|
|
|
this.updateCache = this.updateCache.bind(this)
|
|
|
|
|
|
|
|
this.getImage = this.getImage.bind(this)
|
|
|
|
this.nextImage = this.nextImage.bind(this)
|
|
|
|
this.nextImage = this.nextImage.bind(this)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
cache = []
|
|
|
|
|
|
|
|
imageUrls = {}
|
|
|
|
|
|
|
|
|
|
|
|
// fetch images in browser (we require window.FileReader)
|
|
|
|
// fetch images in browser (we require window.FileReader)
|
|
|
|
componentDidMount() {
|
|
|
|
componentDidMount() {
|
|
|
|
// clear cache when remounted
|
|
|
|
// clear cache when remounted
|
|
|
|
cache = []
|
|
|
|
this.cache = []
|
|
|
|
this.updateCache()
|
|
|
|
this.updateCache()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
async getImage() {
|
|
|
|
|
|
|
|
// circumvent browser caching
|
|
|
|
|
|
|
|
const sig = Math.floor(Math.random() * RAND_RANGE)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const res = await axios.get(`${RANDOM_WALLPAPER_URL}?sig=${sig}`, { responseType: 'blob' })
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// image already in cache?
|
|
|
|
|
|
|
|
if (this.imageUrls[res.request.responseURL]) return
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
this.imageUrls[res.request.responseURL] = true
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
|
|
|
url: res.request.responseURL,
|
|
|
|
|
|
|
|
dataURL: await fileToDataURL(res.data)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
selectImage() {
|
|
|
|
selectImage() {
|
|
|
|
this.setState({ loading: true })
|
|
|
|
this.setState({ loading: true })
|
|
|
|
axios
|
|
|
|
axios
|
|
|
|
.get(largerImage(cache[this.state.cacheIndex].url), { responseType: 'blob' })
|
|
|
|
.get(largerImage(this.cache[this.state.cacheIndex].url), { responseType: 'blob' })
|
|
|
|
.then(res => res.data)
|
|
|
|
.then(res => res.data)
|
|
|
|
.then(this.props.onChange)
|
|
|
|
.then(this.props.onChange)
|
|
|
|
.then(() => this.setState({ loading: false }))
|
|
|
|
.then(() => this.setState({ loading: false }))
|
|
|
@ -58,9 +59,9 @@ export default class extends React.Component {
|
|
|
|
|
|
|
|
|
|
|
|
updateCache() {
|
|
|
|
updateCache() {
|
|
|
|
this.setState({ loading: true })
|
|
|
|
this.setState({ loading: true })
|
|
|
|
Promise.all(range(UPDATE_SIZE).map(getImage))
|
|
|
|
Promise.all(range(UPDATE_SIZE).map(this.getImage))
|
|
|
|
.then(imgs => imgs.filter(img => img)) // remove null
|
|
|
|
.then(imgs => imgs.filter(img => img)) // remove null
|
|
|
|
.then(imgs => (cache = cache.concat(imgs)))
|
|
|
|
.then(imgs => (this.cache = this.cache.concat(imgs)))
|
|
|
|
.then(() => this.setState({ loading: false }))
|
|
|
|
.then(() => this.setState({ loading: false }))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -69,13 +70,13 @@ export default class extends React.Component {
|
|
|
|
|
|
|
|
|
|
|
|
this.setState({ cacheIndex: this.state.cacheIndex + 1 })
|
|
|
|
this.setState({ cacheIndex: this.state.cacheIndex + 1 })
|
|
|
|
|
|
|
|
|
|
|
|
if (this.state.cacheIndex > cache.length - 2) {
|
|
|
|
if (this.state.cacheIndex > this.cache.length - 2) {
|
|
|
|
this.updateCache()
|
|
|
|
this.updateCache()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
render() {
|
|
|
|
render() {
|
|
|
|
const bgImage = cache[this.state.cacheIndex] && cache[this.state.cacheIndex].dataURL
|
|
|
|
const bgImage = this.cache[this.state.cacheIndex] && this.cache[this.state.cacheIndex].dataURL
|
|
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
return (
|
|
|
|
<div className="random-image-container">
|
|
|
|
<div className="random-image-container">
|
|
|
|