window.xhr = function(req, options) { // handle options passed as first argument if (options === undefined) { options = req; if (options.req) req = options.req; else if (options.json) req = JSON.stringify(options.json); } // init xhr if (!options.url) return "url required"; if (!options.type) options.type = "POST"; if (!options.contentType) options.contentType = "application/x-www-form-urlencoded"; // initiate & send request var xhr = new XMLHttpRequest(); xhr.open(options.type, options.url, true); xhr.setRequestHeader("content-type", "application/x-www-form-urlencoded"); if (options.auth) xhr.setRequestHeader("Authorization", options.auth); if (options.headers) { for (var i = 0; i < options.headers.length; i++) { xhr.setRequestHeader(options.headers[i][0], options.headers[i][1]); } } xhr.send(req); // handle response xhr.onreadystatechange = function() { if (this.readyState == 4) { if (String(this.status).startsWith(2)) { if (options.callback) options.callback(this.responseText, false); if (options.onSuccess) options.onSuccess(this.responseText, this.status); } else { if (options.callback) options.callback(this.responseText, this.status); if (options.onError) options.onError(this.responseText, this.status); } } }; }; (function items() { document.addEventListener("click", function(e) { // collapse if (e.target.classList.contains("collapse-icon")) { var item = e.target.parentElement.parentElement; item.classList.toggle("collapsed"); } // add if (e.target.classList.contains("add-icon")) { var item = document.querySelector(".container-sample .item").cloneNode(true); var container = document.querySelector(".container"); container.insertBefore(item, document.querySelector(".container .item")); var textareas = item.querySelectorAll("textarea"); for (var i = 0; i < textareas.length; i++) { resizeTextarea(textareas[i]); } } // delete if (e.target.classList.contains("delete-icon")) { var item = e.target.parentElement.parentElement; item.parentElement.removeChild(item); } }); document.addEventListener("input", function(e) { if (e.target.classList.contains("title")) { var item = e.target.parentElement.parentElement.parentElement; if (item.classList.contains("item")) { item.querySelector(".item-title").innerHTML = e.target.value; } } }); })(); (function textareaResize() { window.resizeTextarea = function(textarea) { textarea.style.height = "auto"; textarea.parentElement.style.height = "auto"; var newHeight = textarea.scrollHeight; var cs = window.getComputedStyle(textarea); // cs == computedStyles var padding = Number(cs.paddingTop.slice(0, -2)) + Number(cs.paddingBottom.slice(0, -2)); textarea.style.height = newHeight+"px"; } window.resizeTextareas = function() { var textareas = document.querySelectorAll("textarea"); for (var i = 0; i < textareas.length; i++) { resizeTextarea(textareas[i]); } } resizeTextareas(); document.addEventListener("input", function(e) { if (e.target.tagName == "TEXTAREA") { resizeTextarea(e.target); } }); })(); var pat = localStorage.getItem("pat"); var gistId = localStorage.getItem("gistId"); function getFilename(pat) { return { json: "LaRSS-"+pat.slice(0,4)+".json", rss: "LaRSS-"+pat.slice(0,4)+".rss" }; } load(pat); function load(pat, callback) { if (pat) { // if gistId is already saved, load it. Otherwise, find the gistId if (gistId) { findGist(pat, gistId, function(content, rssURL) { // if the gist was found, load it. Otherwise if (content) { gistFound(content, rssURL); if (callback) callback(); } else { findGistId(pat, function(id) { if (id) { findGist(pat, id, function(content, rssURL) { gistFound(content, rssURL); if (callback) callback(); resizeTextareas(); }); } else { createGist(pat, function(id, content, rssURL) { localStorage.setItem("gistId", id); gistId = id; gistFound(content, rssURL); if (callback) callback(); }); } }); } }); } else { findGistId(pat, function(id) { if (id) { findGist(pat, id, function(content, rssURL) { gistFound(content, rssURL); if (callback) callback(); resizeTextareas(); }); } else { createGist(pat, function(id, content, rssURL) { localStorage.setItem("gistId", id); gistId = id; gistFound(content, rssURL); if (callback) callback(); }); } }); } } else { showPATdialog(); } } function getGistPermaLink(old) { var start = old.indexOf("/raw/") + 4; var end = old.indexOf("/LaRSS"); return old.slice(0, start)+old.slice(end); } function gistFound(json, rssURL) { rssURL = getGistPermaLink(rssURL); var container = document.querySelector(".container"); container.innerHTML = ''; container.innerHTML += ''; container.innerHTML += ''; var gi = document.querySelector(".container-sample .general-info").cloneNode(true); // generalInfo var gio = json.generalInfo; // generalInfoObject var ia = json.items; // itemsArray container.appendChild(gi); gi.querySelector("input.title").value = gio.title; gi.querySelector("input.author").value = gio.author; gi.querySelector("input.subtitle").value = gio.subtitle; gi.querySelector("textarea.description").value = gio.description; gi.querySelector("input.link").value = gio.link; gi.querySelector("input.imageURL").value = gio.imageURL; gi.querySelector('select.language').value = gio.language; gi.querySelector('select.category').value = gio.category; gi.querySelector('select.explicit').value = gio.explicit; gi.querySelector("input.copyright").value = gio.copyright; gi.querySelector("input.name").value = gio.name; gi.querySelector("input.email").value = gio.email; for (var i = 0; i < json.items.length; i++) { var item = document.querySelector(".container-sample .item").cloneNode(true); container.appendChild(item); item.querySelector("input.guid").value = ia[i].guid; item.querySelector("input.title").value = ia[i].title; item.querySelector("h3.item-title").innerHTML = ia[i].title; item.querySelector("input.audioURL").value = ia[i].audioURL; item.querySelector("input.imageURL").value = ia[i].imageURL; item.querySelector('select.explicit').value = ia[i].explicit; item.querySelector("input.date").value = ia[i].date; item.querySelector("input.duration").value = ia[i].duration; item.querySelector("textarea.summary").value = ia[i].summary; } resizeTextareas(); } function save(callback) { var container = document.querySelector(".container"); var gi = container.querySelector(".general-info"); // generalInfo var gio = {}; // generalInfoObject gio.title = gi.querySelector("input.title").value; gio.author = gi.querySelector("input.author").value; gio.subtitle = gi.querySelector("input.subtitle").value; gio.description = gi.querySelector("textarea.description").value; gio.link = gi.querySelector("input.link").value; gio.imageURL = gi.querySelector("input.imageURL").value; gio.language = gi.querySelector('select.language').value; gio.category = gi.querySelector('select.category').value; gio.explicit = gi.querySelector('select.explicit').value; gio.copyright = gi.querySelector("input.copyright").value; gio.name = gi.querySelector("input.name").value; gio.email = gi.querySelector("input.email").value; var items = container.querySelectorAll(".item"); // generalInfo var ia = []; // itemsArray for (var i = 0; i < items.length; i++) { ia[i] = {}; ia[i].guid = items[i].querySelector("input.guid").value ia[i].title = items[i].querySelector("input.title").value ia[i].title = items[i].querySelector("h3.item-title").innerHTML ia[i].audioURL = items[i].querySelector("input.audioURL").value ia[i].imageURL = items[i].querySelector("input.imageURL").value ia[i].explicit = items[i].querySelector('select.explicit').value ia[i].date = items[i].querySelector("input.date").value ia[i].duration = items[i].querySelector("input.duration").value ia[i].summary = items[i].querySelector("textarea.summary").value } var json = { generalInfo: gio, items: ia }; var xml = generateXML(json); updateGist(gistId, json, xml, function(id) { if (id) { console.log("saved"); if (callback) callback(true); } else { console.log("not saved"); if (callback) callback(false); } }); } function updateGist(gistId, json, xml, callback) { var req = { files: {} }; req.files[getFilename(pat).json] = { content: JSON.stringify(json) }; req.files[getFilename(pat).rss] = { content: xml }; xhr({ url: "https://api.github.com/gists/"+gistId, auth: "token "+pat, type: "POST", json: req, onSuccess: function(res) { res = JSON.parse(res); console.log("----------------------------------- updateGist suc"); console.log(res); callback(res.id, new Date(res.updated_at)); }, onError: function(res, code) { res = JSON.parse(res); console.log("----------------------------------- updateGist err"); console.log(code); console.log(res); callback(false); } }); } document.addEventListener("click", function(e) { if (e.target.classList.contains("save-button")) { e.target.classList.add("saving"); e.target.innerHTML = "Saving..."; save(function(success) { if (success) { e.target.classList.remove("saving"); e.target.classList.add("saved"); e.target.innerHTML = "Saved"; setTimeout(function() { e.target.classList.remove("saved"); e.target.innerHTML = "Save"; },3000); } else { e.target.classList.remove("saving"); e.target.classList.add("error"); e.target.innerHTML = "Error saving :l"; } }); } }); function showPATdialog() { var dialog = document.querySelector(".pat-dialog"); dialog.classList.add("visible"); } (function patDialog() { var button = document.querySelector(".pat-settings"); var dialog = document.querySelector(".pat-dialog"); var patInput = dialog.querySelector("input.pat"); if (pat) patInput.value = pat; button.addEventListener("click", function(e) { showPATdialog(); }); var saveButton = dialog.querySelector("button.save-pat"); saveButton.addEventListener("click", function() { console.log("saving access token"); // save personal access token pat = patInput.value; localStorage.setItem("pat", pat); jsonGistId = null; rssGistId = null; localStorage.removeItem("gistId"); dialog.classList.add("saving"); load(pat, function() { dialog.classList.remove("saving"); dialog.classList.remove("visible"); }); }); document.addEventListener("click", function(e) { if (e.target.classList.contains("dialog-container")) { e.target.classList.remove("visible"); } }); })(); function findGist(pat, gistId, callback) { xhr({ url: "https://api.github.com/gists/"+gistId, auth: "token "+pat, type: "GET", req: "", onSuccess: function(gist) { gist = JSON.parse(gist); console.log("----------------------------------- findGist suc"); console.log(gist); var jsonFile = gist.files[getFilename(pat).json]; var rssFile = gist.files[getFilename(pat).rss]; callback(JSON.parse(jsonFile.content), rssFile.raw_url); }, onError: function(res, code) { res = JSON.parse(res); console.log("----------------------------------- findGist err"); console.log(code); console.log(res); callback(false); } }); } function generateXML(json) { var xml = ''; xml += '\n'; xml += '\n'; xml += ' \n'; xml += ' ' +json.generalInfo.title+ '\n'; xml += ' ' +json.generalInfo.link+ '\n'; xml += ' ' +json.generalInfo.language+ '\n'; xml += ' ' +json.generalInfo.copyright+ '\n'; xml += ' ' +json.generalInfo.subtitle+ '\n'; xml += ' ' +json.generalInfo.author+ '\n'; xml += ' ' +json.generalInfo.description+ '\n'; xml += ' \n'; xml += ' ' +json.generalInfo.name+ '\n'; xml += ' ' +json.generalInfo.email+ '\n'; xml += ' \n'; xml += ' \n'; xml += ' \n'; xml += ' ' +json.generalInfo.explicit+ '\n'; for (var i = 0; i < json.items.length; i++) { xml += ' \n'; xml += ' ' +json.items[i].title+ '\n'; xml += ' ' +json.items[i].summary+ '\n'; xml += ' \n'; xml += ' \n'; xml += ' ' +json.items[i].guid+ '\n'; xml += ' ' +json.items[i].date+ '\n'; xml += ' ' +json.items[i].duration+ '\n'; xml += ' ' +json.items[i].explicit+ '\n'; xml += ' \n'; } xml += ' \n'; xml += '\n'; return xml; } function createGist(pat, callback) { var req = { description: "RSS Gist created by LaRSS", files: {} }; var defaultJSON = { generalInfo: { title: "", author: "", subtitle: "", description: "", link: "", imageURL: "", explicit: "no", language: "en-us", category: "Music", copyright: "", name: "", email: "" }, items: [ { guid: "", title: "New Item", audioURL: "", imageURL: "", explicit: "no", date: "Wed, 25 Oct 2017 22:00:00 CET", duration: "", summary: "" } ] }; req.files[getFilename(pat).json] = { content: JSON.stringify(defaultJSON) }; req.files[getFilename(pat).rss] = { content: "empty rn" }; xhr({ url: "https://api.github.com/gists", auth: "token "+pat, type: "POST", json: req, onSuccess: function(gist) { gist = JSON.parse(gist); console.log("----------------------------------- createGist suc"); console.log(gist); var rssFile = gist.files[getFilename(pat).rss]; callback(gist.id, defaultJSON, rssFile.raw_url); }, onError: function(res, code) { res = JSON.parse(res); console.log("----------------------------------- createGist err"); console.log(code); console.log(res); } }); } function findGistId(pat, callback) { xhr({ url: "https://api.github.com/gists", auth: "token "+pat, type: "GET", req: "", onSuccess: function(gists) { gists = JSON.parse(gists); console.log("----------------------------------- findgistid suc"); console.log(gists); for (var i = 0; i < gists.length; i++) { if (gists[i].files[getFilename(pat).json]) { callback(gists[i].id); localStorage.setItem("gistId", gists[i].id); return; } } callback(false); }, onError: function(res, code) { res = JSON.parse(res); console.log("----------------------------------- findgistid err"); console.log(code); console.log(res); callback(false); } }); }