Created
May 20, 2017 19:56
-
-
Save monteith/e082e604b0fb08a544eccde9935b66e0 to your computer and use it in GitHub Desktop.
reddit rx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const nextButton = document.getElementById("next"); | |
const backButton = document.getElementById("back"); | |
const subSelect = document.getElementById("sub"); | |
const img = document.getElementById("img"); | |
const loading = document.getElementById("loading"); | |
const LOADING_ERROR_URL = "https://jhusain.github.io/reddit-image-viewer/error.png"; | |
const Observable = Rx.Observable; | |
// function which returns an array of image URLs for a given reddit sub | |
// getSubImages("pics") -> | |
// [ | |
// "https://upload.wikimedia.org/wikipedia/commons/3/36/Hopetoun_falls.jpg", | |
// "https://upload.wikimedia.org/wikipedia/commons/3/38/4-Nature-Wallpapers-2014-1_ukaavUI.jpg", | |
// ... | |
// ] | |
function getSubImages(sub) { | |
const cachedImages = localStorage.getItem(sub); | |
if (cachedImages) { | |
return Observable.of(JSON.parse(cachedImages)); | |
} | |
else { | |
const url = `https://www.reddit.com/r/${sub}/.json?limit=200&show=all`; | |
// defer ensure new Observable (and therefore) promise gets created | |
// for each subscription. This ensures functions like retry will | |
// issue additional requests. | |
return Observable.defer(() => | |
Observable.fromPromise( | |
fetch(url). | |
then(res => res.json()). | |
then(data => { | |
const images = | |
data.data.children.map(image => image.data.url); | |
localStorage.setItem(sub, JSON.stringify(images)); | |
return images; | |
}))); | |
} | |
} | |
const subs = Observable | |
.concat( | |
Observable.of(subSelect.value), | |
Observable | |
.fromEvent(subSelect, 'change') | |
.map(ev => ev.target.value) | |
); | |
const nexts = Observable | |
.fromEvent(nextButton, 'click') | |
.map(() => { | |
}); | |
const backs = Observable | |
.fromEvent(backButton, 'click') | |
.map(() => { | |
}); | |
const offsets = | |
Observable.merge( | |
nexts.map(() => 1), | |
backs.map(() => -1) | |
); | |
const indices = | |
Observable.concat( | |
Observable.of(0), | |
offsets.scan((acc, curr) => acc + curr, 0) | |
); | |
// ---------------------- INSERT CODE HERE --------------------------- | |
// This "images" Observable is a dummy. Replace it with a stream of each | |
// image in the current sub which is navigated by the user. | |
const images = | |
subs. | |
map(sub => | |
getSubImages(sub). | |
map( images => | |
indices.map(index => images[index])). | |
switch()). | |
switch(); | |
/*images.subscribe({ | |
next(url) { | |
console.log(url); | |
} | |
});*/ | |
images.subscribe({ | |
next(url) { | |
// hide the loading image | |
loading.style.visibility = "hidden"; | |
// set Image source to URL | |
img.src = url; | |
}, | |
error(e) { | |
alert("I'm having trouble loading the images for that sub. Please wait a while, reload, and then try again later.") | |
} | |
}); | |
const img = new Image(src); | |
img.onload = function () { | |
}; | |
img.onerror = function () { | |
}; | |
// This "actions" Observable is a placeholder. Replace it with an | |
// observable that notifies whenever a user performs an action, | |
// like changing the sub or navigating the images | |
const actions = Observable | |
.merge(subs, nexts, backs); | |
actions.subscribe(() => loading.style.visibility = "visible"); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment