diff --git a/css/screen.css b/css/screen.css index e5a63d0..97c1bc7 100644 --- a/css/screen.css +++ b/css/screen.css @@ -73,6 +73,11 @@ button:active, a:active, .button:active { padding: 10px 20px; } +#login .backends label { + display: block; + margin-bottom: 1px; +} + label { display: none; } @@ -356,4 +361,4 @@ canvas { #settings .button.small { width: 20%; text-align: center; -} \ No newline at end of file +} diff --git a/index.html b/index.html index 7d5ec18..3b158b8 100644 --- a/index.html +++ b/index.html @@ -62,6 +62,10 @@ +

+ + +

diff --git a/js/App.js b/js/App.js index 750017c..ea06441 100644 --- a/js/App.js +++ b/js/App.js @@ -92,10 +92,10 @@ App.prototype.after_login = function(backend) { this.changeToPage("#list"); - if(backend == "TinyTinyRSS") { - this.backend = new TinyTinyRSS(this, localStorage.server_url, localStorage.session_id); - } else if(backend == "OwnCloud") { + if(backend == "OwnCloud") { this.backend = new OwnCloud(this, localStorage.server_url, localStorage.session_id); + } else { + this.backend = new TinyTinyRSS(this, localStorage.server_url, localStorage.session_id); } this.reload(); }; @@ -135,7 +135,7 @@ App.prototype.setColor = function(color) { App.prototype.reload = function() { this.unread_articles = []; $("#all-read").innerHTML = "❌"; - this.backend.getUnreadFeeds(this.gotUnreadFeeds.bind(this)); + this.backend.reload(this.gotUnreadFeeds.bind(this)); }; App.prototype.gotUnreadFeeds = function(new_articles) { @@ -214,7 +214,9 @@ App.prototype.updateList = function() { this.updatePieChart(); }; -App.prototype.updatePieChart = function(all, unread) { +App.prototype.updatePieChart = function() { + + if(!this.unread_articles) return; // happens on loginpage var all = this.unread_articles.length; var unread = 0; @@ -316,7 +318,7 @@ App.prototype.setCurrentRead = function() { if(!article.set_unread) { article.unread = false; this.updateList(); - this.backend.setArticleRead(article.id); + this.backend.setArticleRead(article); } article.set_unread = false; @@ -339,39 +341,39 @@ App.prototype.toggleCurrentUnread = function() { } this.updateList(); - this.backend.setArticleUnread(article.id); + this.backend.setArticleUnread(article); }; App.prototype.toggleAllRead = function() { if($("#all-read").innerHTML == "❌") { // set all read - var ids = []; + var articles = []; for (var i = 0; i < this.unread_articles.length; i++) { var article = this.unread_articles[i]; article.unread = false; article.set_unread = false; - ids.push(article.id); + articles.push(article); } $("#all-read").innerHTML = "✓"; this.updateList(); - this.backend.setArticleRead(ids.join(",")); + this.backend.setArticlesRead(articles); } else { - var ids = []; + var articles = []; for (var i = 0; i < this.unread_articles.length; i++) { var article = this.unread_articles[i]; article.unread = true; article.set_unread = false; - ids.push(article.id); + articles.push(article); } $("#all-read").innerHTML = "❌"; this.updateList(); - this.backend.setArticleUnread(ids.join(",")); + this.backend.setArticlesUnread(articles); } }; @@ -383,13 +385,13 @@ App.prototype.toggleStarred = function() { if(!article.marked) { article.marked = true; this.updateList(); - this.backend.setArticleStarred(article.id); + this.backend.setArticleStarred(article); $("#setstarred").innerHTML = "★"; } else { article.marked = false; this.updateList(); - this.backend.setArticleUnStarred(article.id); + this.backend.setArticleUnstarred(article); $("#setstarred").innerHTML = "☆"; } diff --git a/js/Login.js b/js/Login.js index bf0cc27..ed96adc 100644 --- a/js/Login.js +++ b/js/Login.js @@ -25,6 +25,9 @@ Login.prototype.authenticate = function(e) { e.preventDefault(); e.stopPropagation(); + var backend = "TinyTinyRSS"; + if($("#login form").backend[1].checked) backend = "OwnCloud"; + var server_url = $("#url").value; var user = $("#un").value; var password = $("#pw").value; @@ -44,7 +47,8 @@ Login.prototype.authenticate = function(e) { } var _this = this; - if(true) { + + if(backend == "OwnCloud") { OwnCloud.login(server_url, user, password, function(data) { if(data.version) { var auth = btoa(user + ':' + password); diff --git a/js/OwnCloud.js b/js/OwnCloud.js index db6eb6f..34694a8 100644 --- a/js/OwnCloud.js +++ b/js/OwnCloud.js @@ -3,9 +3,8 @@ function OwnCloud(app, server_url, user_pass_btoa) { this.server_url = server_url; this.session_id = user_pass_btoa; this.feeds = {}; - if(localStorage.feeds) { - this.feeds = JSON.parse(localStorage.feeds); - } + var feeds = localStorage.feeds; + if(feeds) this.feeds = JSON.parse(feeds); window.addEventListener("offline", this.onoffline.bind(this)); window.addEventListener("online", this.ononline.bind(this)); @@ -16,22 +15,14 @@ OwnCloud.prototype.onoffline = function() { }; OwnCloud.prototype.ononline = function() { - var read_articles = localStorage.read_articles; - if (read_articles ) { - read_articles = JSON.parse(localStorage.read_articles); - this.setArticleRead(read_articles.join(","), function() { - localStorage.read_articles = null; - }); - } - - var unread_articles = localStorage.unread_articles; - if (unread_articles) { - unread_articles = JSON.parse(unread_articles); - this.setArticleUnread(unread_articles.join(","), function() { - localStorage.unread_articles(); - }); - } + ["read", "unread", "starred", "unstarred"].forEach(function(type) { + var articles = localStorage[type + "_articles"]; + if(articles) { + var callback = function(ok) { if(ok) localStorage[type + "_articles"] = null } + this.call("setArticles" + type.capitalize(), [JSON.parse(articles), callback]); + } + }); }; OwnCloud.prototype.doOperation = function(method, operation, new_options, callback) { @@ -69,13 +60,16 @@ OwnCloud.prototype.doOperation = function(method, operation, new_options, callba } xhr.open(method, url, true); xhr.withCredentials = true; - //var auth = btoa(user + ':' + password); xhr.setRequestHeader('Authorization', 'Basic ' + this.session_id); var body = JSON.stringify(options); - console.log(body) xhr.send(body); } +OwnCloud.prototype.reload = function(callback) { + var _this = this; + this.getFeeds(function() { _this.getUnreadFeeds(callback); }); +}; + OwnCloud.prototype.getUnreadFeeds = function(callback, skip) { if(skip) { skip = skip[skip.length - 1].id; @@ -90,8 +84,6 @@ OwnCloud.prototype.getUnreadFeeds = function(callback, skip) { }; var _this = this; - console.log(_this.toString()) - this.doOperation("GET", "items", options, function(data) { var items = data.items; @@ -130,67 +122,73 @@ OwnCloud.prototype.getFeeds = function(callback) { }); }; -OwnCloud.prototype.setArticleRead = function(article_id, callback) { - var items = [article_id]; - if(typeof article_id == "string") items = article_id.split(","); +OwnCloud.prototype.setArticlesRead = function(articles, callback) { var options = { - items: items, + items: articles.map(function(o) { return o.id; }), }; if (navigator.onLine) { this.doOperation("PUT", "items/read/multiple", options, callback); } else { - var read_articles = localStorage.read_articles; - if(typeof read_articles !== "undefined") read_articles = JSON.parse(read_articles); - else read_articles = []; - read_articles.concat(options.items); - localStorage.read_articles = JSON.stringify(read_articles); + this.append("read_articles", articles); } -}; +} -OwnCloud.prototype.setArticleUnread = function(article_id, callback) { - var items = [article_id]; - if(typeof article_id == "string") items = article_id.split(","); +OwnCloud.prototype.setArticleRead = function(article, callback) { + this.setArticlesRead([article], callback); +} +OwnCloud.prototype.setArticlesUnread = function(articles, callback) { + var options = { - items: items, + items: articles.map(function(o) { return o.id; }), }; if (navigator.onLine) this.doOperation("PUT", "items/unread/multiple", options, callback); else { - var unread_articles = localStorage.unread_articles; - if (typeof unread_articles !== "undefined") unread_articles = JSON.parse(unread_articles); - else unread_articles = []; - unread_articles.concat(options.items); - localStorage.unread_articles = JSON.stringify(unread_articles); + this.append("unread_articles", articles); } }; -OwnCloud.prototype.setArticleStarred = function(article_id) { +OwnCloud.prototype.setArticleUnread = function(article, callback) { + this.setArticlesUnread([article], callback); +} + +OwnCloud.prototype.setArticlesStarred = function(articles, callback) { + console.log(JSON.stringify(articles)) var options = { - article_ids: article_id, - mode: 1, - field: 0 + items: articles.map(function(o) { return { feedId: o.feed_id, guidHash: o.guid_hash }; }) }; if (navigator.onLine) { - this.doOperation("updateArticle", options); - } + this.doOperation("PUT", "items/star/multiple", options, callback); + } else { + this.append("starred_articles", articles); + } }; -OwnCloud.prototype.setArticleUnStarred = function(article_id) { +OwnCloud.prototype.setArticleStarred = function(article, callback) { + this.setArticlesStarred([article], callback); +} + +OwnCloud.prototype.setArticlesUnstarred = function(articles, callback) { + var options = { - article_ids: article_id, - mode: 0, - field: 0 + items: articles.map(function(o) { return { feedId: o.feed_id, guidHash: o.guid_hash }; }) }; if (navigator.onLine) { - this.doOperation("updateArticle", options); - } + this.doOperation("PUT", "items/unstar/multiple", options, callback); + } else { + this.append("unstarred_articles", articles); + } }; +OwnCloud.prototype.setArticleUnstarred = function(articles, callback) { + this.setArticlesUnstarred([articles], callback); +} + OwnCloud.prototype.normalize_article = function(article) { var feed = this.feeds[article.feedId]; var feed_title = ""; @@ -200,6 +198,7 @@ OwnCloud.prototype.normalize_article = function(article) { return { id: article.id, + guid_hash: article.guidHash, title: article.title, content: article.body, feed_title: feed_title, @@ -220,6 +219,17 @@ OwnCloud.prototype.getFeedFor = function(o) { return this.feeds[o.feedId]; }; +OwnCloud.prototype.append = function(key, array) { + + var tmp = localStorage[key]; + + if (typeof tmp !== "undefined") tmp = JSON.parse(tmp); + else tmp = []; + + tmp.concat(options.items); + localStorage[key] = JSON.stringify(tmp); +}; + OwnCloud.login = function(server_url, user, password, callback) { var url = server_url + "/index.php/apps/news/api/v1-2/version"; diff --git a/js/TinyTinyRSS.js b/js/TinyTinyRSS.js index 1a2a208..4479f49 100644 --- a/js/TinyTinyRSS.js +++ b/js/TinyTinyRSS.js @@ -12,22 +12,14 @@ TinyTinyRSS.prototype.onoffline = function() { }; TinyTinyRSS.prototype.ononline = function() { - var read_articles = localStorage.read_articles; - if (read_articles ) { - read_articles = JSON.parse(localStorage.read_articles); - this.setArticleRead(read_articles.join(","), function() { - localStorage.read_articles = null; - }); - } - - var unread_articles = localStorage.unread_articles; - if (unread_articles) { - unread_articles = JSON.parse(unread_articles); - this.setArticleUnread(unread_articles.join(","), function() { - localStorage.unread_articles(); - }); - } + ["read", "unread", "starred", "unstarred"].forEach(function(type) { + var articles = localStorage[type + "_articles"]; + if(articles) { + var callback = function(ok) { if(ok) localStorage[type + "_articles"] = null } + this.call("setArticles" + type.capitalize(), [JSON.parse(articles), callback]); + } + }); }; TinyTinyRSS.prototype.doOperation = function(operation, new_options, callback) { @@ -62,6 +54,10 @@ TinyTinyRSS.prototype.doOperation = function(operation, new_options, callback) { xhr.send(JSON.stringify(options)); } +TinyTinyRSS.prototype.reload = function(callback) { + this.getUnreadFeeds(callback, []); +}; + TinyTinyRSS.prototype.getUnreadFeeds = function(callback, skip) { skip = skip.length; var options = { @@ -75,63 +71,92 @@ TinyTinyRSS.prototype.getUnreadFeeds = function(callback, skip) { this.doOperation("getHeadlines", options, callback); } -TinyTinyRSS.prototype.setArticleRead = function(article_id) { +TinyTinyRSS.prototype.setArticlesRead = function(articles, callback) { + var options = { - article_ids: article_id, + article_ids: articles.map(function(o) { return o.id }).join(","), mode: 0, field: 2 }; + if (navigator.onLine) { + this.doOperation("updateArticle", options, callback); + } else { + this.append("read_articles", articles); + } +}; + +TinyTinyRSS.prototype.setArticleRead = function(article, callback) { + this.setArticlesRead([article], callback); +}; + + +TinyTinyRSS.prototype.setArticlesUnread = function(articles, callback) { + + var options = { + article_ids: articles.map(function(o) { return o.id }).join(","), + mode: 1, + field: 2 + }; + + if (navigator.onLine) { + this.doOperation("updateArticle", options, callback); + } else { + this.append("unread_articles", articles); + } +}; + +TinyTinyRSS.prototype.setArticleUnread = function(article, callback) { + this.setArticlesUnread([article], callback); +}; + +TinyTinyRSS.prototype.setArticlesStarred = function(articles, callback) { + + var options = { + article_ids: articles.map(function(o) { return o.id }).join(","), + mode: 1, + field: 0 + }; + if (navigator.onLine) { this.doOperation("updateArticle", options); } else { - var read_articles = localStorage.read_articles; - if(typeof read_articles !== "undefined") read_articles = JSON.parse(read_articles); - else read_articles = []; - read_articles.push(article_id); - localStorage.read_articles = JSON.stringify(read_articles); + this.append("starred_articles", articles); } }; -TinyTinyRSS.prototype.setArticleStarred = function(article_id) { - var options = { - article_ids: article_id, - mode: 1, - field: 0 - }; - - if (navigator.onLine) { - this.doOperation("updateArticle", options); - } +TinyTinyRSS.prototype.setArticleStarred = function(article, callback) { + this.setArticlesStarred([article], callback); }; -TinyTinyRSS.prototype.setArticleUnStarred = function(article_id) { +TinyTinyRSS.prototype.setArticlesUnstarred = function(articles, callback) { + var options = { - article_ids: article_id, + article_ids: articles.map(function(o) { return o.id}).join(","), mode: 0, field: 0 }; if (navigator.onLine) { - this.doOperation("updateArticle", options); - } + this.doOperation("updateArticle", options, callback); + } else { + this.append("unstarred_articles", articles); + } }; -TinyTinyRSS.prototype.setArticleUnread = function(article_id) { - var options = { - article_ids: article_id, - mode: 1, - field: 2 - }; +TinyTinyRSS.prototype.setArticleUnstarred = function(article, callback) { + this.setArticlesUnstarred([article], callback); +}; - if (navigator.onLine) this.doOperation("updateArticle", options); - else { - var unread_articles = localStorage.unread_articles; - if (typeof unread_articles !== "undefined") unread_articles = JSON.parse(unread_articles); - else unread_articles = []; - unread_articles.push(article_id); - localStorage.unread_articles = JSON.stringify(unread_articles); - } +TinyTinyRSS.prototype.append = function(key, array) { + + var tmp = localStorage[key]; + + if (typeof tmp !== "undefined") tmp = JSON.parse(tmp); + else tmp = []; + + tmp.concat(options.items); + localStorage[key] = JSON.stringify(tmp); }; TinyTinyRSS.prototype.logOut = function() { diff --git a/js/application.js b/js/application.js index 5e63e8b..6ab7903 100644 --- a/js/application.js +++ b/js/application.js @@ -50,5 +50,9 @@ String.prototype.stripHTML = function() { return this.replace(/(<([^>]+)>)/ig, ""); } +String.prototype.capitalize = function() { + return this.charAt(0).toUpperCase() + this.slice(1); +} + if(!window.app) window.app = new App();