From: Andrew Dolgov Date: Mon, 24 Dec 2012 06:16:01 +0000 (+0400) Subject: move digest to a separate plugin X-Git-Tag: 1.7.0~146 X-Git-Url: https://git.wh0rd.org/?a=commitdiff_plain;h=ac22075182f1d9b8dfd0c481e943d812e63f7789;p=tt-rss.git move digest to a separate plugin --- diff --git a/classes/rpc.php b/classes/rpc.php index 2bec8c54..4e08c3dc 100644 --- a/classes/rpc.php +++ b/classes/rpc.php @@ -594,60 +594,6 @@ class RPC extends Handler_Protected { } } - function digestgetcontents() { - $article_id = db_escape_string($_REQUEST['article_id']); - - $result = db_query($this->link, "SELECT content,title,link,marked,published - FROM ttrss_entries, ttrss_user_entries - WHERE id = '$article_id' AND ref_id = id AND owner_uid = ".$_SESSION['uid']); - - $content = sanitize($this->link, db_fetch_result($result, 0, "content")); - $title = strip_tags(db_fetch_result($result, 0, "title")); - $article_url = htmlspecialchars(db_fetch_result($result, 0, "link")); - $marked = sql_bool_to_bool(db_fetch_result($result, 0, "marked")); - $published = sql_bool_to_bool(db_fetch_result($result, 0, "published")); - - print json_encode(array("article" => - array("id" => $article_id, "url" => $article_url, - "tags" => get_article_tags($this->link, $article_id), - "marked" => $marked, "published" => $published, - "title" => $title, "content" => $content))); - } - - function digestupdate() { - $feed_id = db_escape_string($_REQUEST['feed_id']); - $offset = db_escape_string($_REQUEST['offset']); - $seq = db_escape_string($_REQUEST['seq']); - - if (!$feed_id) $feed_id = -4; - if (!$offset) $offset = 0; - - $reply = array(); - - $reply['seq'] = $seq; - - $headlines = api_get_headlines($this->link, $feed_id, 30, $offset, - '', ($feed_id == -4), true, false, "unread", "updated DESC", 0, 0); - - $reply['headlines'] = array(); - $reply['headlines']['title'] = getFeedTitle($this->link, $feed_id); - $reply['headlines']['content'] = $headlines; - - print json_encode($reply); - } - - function digestinit() { - $tmp_feeds = api_get_feeds($this->link, -4, true, false, 0); - - $feeds = array(); - - foreach ($tmp_feeds as $f) { - if ($f['id'] > 0 || $f['id'] == -4) array_push($feeds, $f); - } - - print json_encode(array("feeds" => $feeds)); - } - function catchupFeed() { $feed_id = db_escape_string($_REQUEST['feed_id']); $is_cat = db_escape_string($_REQUEST['is_cat']) == "true"; diff --git a/digest.css b/digest.css deleted file mode 100644 index 54568e3b..00000000 --- a/digest.css +++ /dev/null @@ -1,337 +0,0 @@ -body#ttrssDigest { - color : black; - font-family : sans-serif; - font-size : 12px; - margin : 0px; - background : url("images/tile.png"); -} - -a { - color : #0069D8; - text-decoration : none; -} - -a:hover { - color : gray; -} - -#header a, #footer a { - color : gray; -} - -#header a:hover, #footer a:hover { - color : #0069D8; -} - -#header { - font-size : 13px; - font-family : "Segoe UI", Tahoma, sans-serif; - padding : 5px 5px 5px 1.5em; - color : gray; - position : absolute; - top : 0px; - height : 30px; - left : 0px; - right : 0px; - color : #a0a0a0; -} - -#header span.title { - font-weight : bold; - font-style : italic; -} - -#header div.links { - position : absolute; - right : 1.5em; -} - -#search { - float : right; - clear : left; - -} - -#title { -} - -#latest { - padding : 5px; -} - -#content { - position : absolute; - left : 0px; - top : 30px; - right : 0px; - bottom : 0px; - -webkit-transition: left 0.2s linear, right 0.2s linear; - -moz-transition: left 0.2s linear, right 0.2s linear; - transition: left 0.2s linear, right 0.2s linear; -} - -#article { - position : absolute; - overflow : auto; - right : 0px; - width : 60%; - bottom : 0px; - top : 30px; - background : white; - z-index : -1; - opacity : 0; - -webkit-transition: opacity 0.2s linear; - -moz-transition: opacity 0.2s linear; - transition: opacity 0.2s linear; -} - -#article.visible { - opacity : 1; -} - -#article #article-content h1 { - margin : 0px 0px 10px 0px; - padding : 0px 0px 5px 0px; - font-family : "Segoe UI", Tahoma, sans-serif; - font-size : 21px; - font-weight : bold; - border-width : 0px 0px 3px 0px; - border-style : solid; - border-color : #e0e0e0; - color : gray; -} - -#article #article-content #toolbar { - border-width : 0px 0px 1px 0px; - border-color : #e0e0e0; - border-style : solid; - background : #fafafa; - font-size : 14px; - font-weight : bold; - padding : 5px 10px 5px 10px; - margin : 0px 0px 0px 0px; -} - -#article #article-content { - padding : 0px; - font-size : 16px; -} - -#article #article-content #tags { - color : #a0a0a0; -} - -#article #article-content #ops { - float : right; -} - -#article #article-content #ops img { - cursor : pointer; - margin-right : 0px; - margin-left : 10px; -} - -#article #article-content #inner { - padding : 20px; -} - -#article #article-content img { - max-width : 90%; -} - -#content.move { - left : -300px; - right : 60% -} - -#feeds { - position : absolute; - left : 0px; - width : 300px; - top : -30px; - bottom : 0px; - font-size : 14px; - overflow : auto; - border-width : 0px 3px 0px 0px; - border-color : #88b0f0; - border-style : solid; - background : #eee; -} - -#feeds ul#feeds-content img { - width : 16px; - height : 16px; - vertical-align : middle; - margin-right : 5px; -} - -#feeds ul#feeds-content div.unread-ctr { - color : #d0d0d0; - padding-left : 10px; - float : right; -} - -#feeds ul#feeds-content li { - padding : 10px; - clear : both; - cursor : pointer; - color : #303030; - white-space : nowrap; -} - -#feeds ul#feeds-content li.selected { - background : white; -} - -#feeds ul#feeds-content { - list-style-type : none; - font-weight : bold; - margin : 0px; - padding : 0px; -} - -#headlines { - font-size : 14px; - position : absolute; - left : 303px; - top : 0px; - bottom : 0px; - right : 0px; - overflow : auto; - border-width : 0px 3px 0px 0px; - border-style : solid; - border-color : #88b0f0; -} - -#headlines h1 a { - color : #684C99; -} - -#headlines ul#headlines-content .cb { - vertical-align : middle; - margin-right : 5px; - float : left; -} - -#headlines ul#headlines-content img.icon { - width : 16px; - height : 16px; - vertical-align : middle; - margin-right : 5px; - float : right; -} - -#headlines ul#headlines-content { - list-style-type : none; - color : gray; - margin : 0px; - padding : 0px; -} - -#headlines ul#headlines-content li { - margin : 0px 0px 0px 0px; - padding : 10px; - color : gray; - clear : left; - border-width : 0px 0px 1px 0px; - border-style : solid; - border-color : #e0e0e0; - background : #eee; -} - -#headlines ul#headlines-content a.title { - font-size : 14px; - font-weight : bold; - display : block; - margin-left : 21px; - position : relative; -} - -#headlines ul#headlines-content li.fresh a.title { - color : #007FFF; -} - -#headlines ul#headlines-content li.unread a.title { - color : black; - /* color : #8DB1D6; */ -} - -#headlines ul#headlines-content li.read a.title { - color : gray; -} - -#headlines ul#headlines-content li.unread, -#headlines ul#headlines-content li.fresh { - background-color : white; -} - -#headlines ul#headlines-content li.selected { - background-color : #fff7d5; - border-color : white white #e0e0e0; -} - -#headlines ul#headlines-content img#H-LOADING-IMG { - margin-left : 5px; -} - -#headlines ul#headlines-content div.excerpt { - color : #404040; - cursor : pointer; - margin-top : 5px; -} - -#headlines ul#headlines-content div.content { - color : #404040; -} - -#headlines ul#headlines-content div.content img { - max-width : 75%; -} - -#headlines ul#headlines-content div.body { - margin-left : 21px; - /*margin-left : 42px;*/ -} - -#headlines ul#headlines-content div.info { - font-size : 11px; - margin-top : 5px; -} - -#headlines ul#headlines-content div.info a { - color : gray; -} - -#overlay { - background : white; - left : 0; - top : 0; - height : 100%; - width : 100%; - z-index : 100; - position : absolute; - text-align : center; -} - -#overlay_inner { - margin : 1em; -} - -#overlay img { - vertical-align : middle; -} - -div.fatalError button { - margin-top : 5px; -} - -div.fatalError textarea { - width : 100%; - height : 100px; -} - -div.insensitive { - color : gray; -} - - diff --git a/digest.php b/digest.php deleted file mode 100644 index 7cc17418..00000000 --- a/digest.php +++ /dev/null @@ -1,101 +0,0 @@ - - - - - - Tiny Tiny RSS - - - - - - - - - - - - - - - - - - - - - - -
-
- - - - -
-
- - - -
 
- -
- -
-
-
- -
-
-
-
- - - diff --git a/images/tile.png b/images/tile.png deleted file mode 100644 index 72f2f455..00000000 Binary files a/images/tile.png and /dev/null differ diff --git a/index.php b/index.php index d958e2b8..b86cd0e6 100644 --- a/index.php +++ b/index.php @@ -18,9 +18,15 @@ $mobile = new Mobile_Detect(); + $link = db_connect(DB_HOST, DB_USER, DB_PASS, DB_NAME); + + if (!init_connection($link)) return; + + global $pluginhost; + if (!$_REQUEST['mobile']) { - if ($mobile->isTablet()) { - header('Location: digest.php'); + if ($mobile->isTablet() && $pluginhost->get_plugin("digest")) { + header('Location: backend.php?op=digest'); exit; } else if ($mobile->isMobile()) { header('Location: mobile/index.php'); @@ -28,9 +34,6 @@ } } - $link = db_connect(DB_HOST, DB_USER, DB_PASS, DB_NAME); - - if (!init_connection($link)) return; login_sequence($link); @@ -208,8 +211,10 @@
+ get_plugin("digest")) { ?>
-
+ +
diff --git a/js/digest.js b/js/digest.js deleted file mode 100644 index 241328ab..00000000 --- a/js/digest.js +++ /dev/null @@ -1,852 +0,0 @@ -var last_feeds = []; -var init_params = {}; - -var _active_feed_id = false; -var _update_timeout = false; -var _view_update_timeout = false; -var _feedlist_expanded = false; -var _update_seq = 1; - -function article_appear(article_id) { - try { - new Effect.Appear('A-' + article_id); - } catch (e) { - exception_error("article_appear", e); - } -} - -function catchup_feed(feed_id, callback) { - try { - - var fn = find_feed(last_feeds, feed_id).title; - - if (confirm(__("Mark all articles in %s as read?").replace("%s", fn))) { - - var is_cat = ""; - - if (feed_id < 0) is_cat = "true"; // KLUDGE - - var query = "?op=rpc&method=catchupFeed&feed_id=" + - feed_id + "&is_cat=" + is_cat; - - new Ajax.Request("backend.php", { - parameters: query, - onComplete: function(transport) { - if (callback) callback(transport); - - update(); - } }); - } - - } catch (e) { - exception_error("catchup_article", e); - } -} - -function get_visible_article_ids() { - try { - var elems = $("headlines-content").getElementsByTagName("LI"); - var ids = []; - - for (var i = 0; i < elems.length; i++) { - if (elems[i].id && elems[i].id.match("A-")) { - ids.push(elems[i].id.replace("A-", "")); - } - } - - return ids; - - } catch (e) { - exception_error("get_visible_article_ids", e); - } -} - -function catchup_visible_articles(callback) { - try { - - var ids = get_visible_article_ids(); - - if (confirm(__("Mark %d displayed articles as read?").replace("%d", ids.length))) { - - var query = "?op=rpc&method=catchupSelected" + - "&cmode=0&ids=" + param_escape(ids); - - new Ajax.Request("backend.php", { - parameters: query, - onComplete: function(transport) { - if (callback) callback(transport); - - viewfeed(_active_feed_id, 0); - } }); - - } - - } catch (e) { - exception_error("catchup_visible_articles", e); - } -} - -function catchup_article(article_id, callback) { - try { - var query = "?op=rpc&method=catchupSelected" + - "&cmode=0&ids=" + article_id; - - new Ajax.Request("backend.php", { - parameters: query, - onComplete: function(transport) { - if (callback) callback(transport); - } }); - - } catch (e) { - exception_error("catchup_article", e); - } -} - -function set_selected_article(article_id) { - try { - $$("#headlines-content > li[id*=A-]").each(function(article) { - var id = article.id.replace("A-", ""); - - var cb = article.getElementsByTagName("INPUT")[0]; - - if (id == article_id) { - article.addClassName("selected"); - cb.checked = true; - } else { - article.removeClassName("selected"); - cb.checked = false; - } - - }); - - } catch (e) { - exception_error("mark_selected_feed", e); - } -} - - -function set_selected_feed(feed_id) { - try { - var feeds = $("feeds-content").getElementsByTagName("LI"); - - for (var i = 0; i < feeds.length; i++) { - if (feeds[i].id == "F-" + feed_id) - feeds[i].className = "selected"; - else - feeds[i].className = ""; - } - - _active_feed_id = feed_id; - - } catch (e) { - exception_error("mark_selected_feed", e); - } -} - -function load_more() { - try { - var pr = $("H-LOADING-IMG"); - - if (pr) Element.show(pr); - - var offset = $$("#headlines-content > li[id*=A-][class*=fresh],li[id*=A-][class*=unread]").length; - - viewfeed(false, offset, false, false, true, - function() { - var pr = $("H-LOADING-IMG"); - - if (pr) Element.hide(pr); - }); - } catch (e) { - exception_error("load_more", e); - } -} - -function update(callback) { - try { - console.log('updating feeds...'); - - window.clearTimeout(_update_timeout); - - new Ajax.Request("backend.php", { - parameters: "?op=rpc&method=digestinit", - onComplete: function(transport) { - fatal_error_check(transport); - parse_feeds(transport); - set_selected_feed(_active_feed_id); - - if (callback) callback(transport); - } }); - - _update_timeout = window.setTimeout('update()', 5*1000); - } catch (e) { - exception_error("update", e); - } -} - -function remove_headline_entry(article_id) { - try { - var elem = $('A-' + article_id); - - if (elem) { - elem.parentNode.removeChild(elem); - } - - } catch (e) { - exception_error("remove_headline_entry", e); - } -} - -function view_update() { - try { - viewfeed(_active_feed_id, _active_feed_offset, false, true, true); - update(); - } catch (e) { - exception_error("view_update", e); - } -} - -function view(article_id) { - try { - $("content").addClassName("move"); - - var a = $("A-" + article_id); - var h = $("headlines"); - - setTimeout(function() { - // below or above viewport, reposition headline - if (a.offsetTop > h.scrollTop + h.offsetHeight || a.offsetTop+a.offsetHeight < h.scrollTop+a.offsetHeight) - h.scrollTop = a.offsetTop - (h.offsetHeight/2 - a.offsetHeight/2); - }, 500); - - new Ajax.Request("backend.php", { - parameters: "?op=rpc&method=digestgetcontents&article_id=" + - article_id, - onComplete: function(transport) { - fatal_error_check(transport); - - var reply = JSON.parse(transport.responseText); - - if (reply) { - var article = reply['article']; - - var mark_part = ""; - var publ_part = ""; - - var tags_part = ""; - - if (article.tags.length > 0) { - tags_part = " " + __("in") + " "; - - for (var i = 0; i < Math.min(5, article.tags.length); i++) { - //tags_part += "" + - // article.tags[i] + ", "; - - tags_part += article.tags[i] + ", "; - } - - tags_part = tags_part.replace(/, $/, ""); - tags_part = "" + tags_part + ""; - - } - - if (article.marked) - mark_part = ""; - else - mark_part = ""; - - if (article.published) - publ_part = ""; - else - publ_part = ""; - - var tmp = "
" + - "
" + - mark_part + - publ_part + - "
" + - "

" + "" + - article.title + "" + "

" + - "
" + - tags_part + - "
" + - article.content + "
"; - - $("article-content").innerHTML = tmp; - $("article").addClassName("visible"); - - set_selected_article(article.id); - - catchup_article(article_id, - function() { - $("A-" + article_id).addClassName("read"); - }); - - } else { - elem.innerHTML = __("Error: unable to load article."); - } - } - }); - - - return false; - } catch (e) { - exception_error("view", e); - } -} - -function close_article() { - $("content").removeClassName("move"); - $("article").removeClassName("visible"); -} - -function viewfeed(feed_id, offset, replace, no_effects, no_indicator, callback) { - try { - - if (!feed_id) feed_id = _active_feed_id; - if (offset == undefined) offset = 0; - if (replace == undefined) replace = (offset == 0); - - _update_seq = _update_seq + 1; - - if (!offset) $("headlines").scrollTop = 0; - - var query = "backend.php?op=rpc&method=digestupdate&feed_id=" + - param_escape(feed_id) + "&offset=" + offset + - "&seq=" + _update_seq; - - console.log(query); - - var img = false; - - if ($("F-" + feed_id)) { - img = $("F-" + feed_id).getElementsByTagName("IMG")[0]; - - if (img && !no_indicator) { - img.setAttribute("orig_src", img.src); - img.src = 'images/indicator_tiny.gif'; - } - } - - new Ajax.Request("backend.php", { - parameters: query, - onComplete: function(transport) { - Element.hide("overlay"); - - fatal_error_check(transport); - parse_headlines(transport, replace, no_effects); - set_selected_feed(feed_id); - _active_feed_offset = offset; - - if (img && !no_indicator) - img.src = img.getAttribute("orig_src"); - - if (callback) callback(transport); - - } }); - - } catch (e) { - exception_error("view", e); - } -} - -function find_article(articles, article_id) { - try { - for (var i = 0; i < articles.length; i++) { - if (articles[i].id == article_id) - return articles[i]; - } - - return false; - - } catch (e) { - exception_error("find_article", e); - } -} - -function find_feed(feeds, feed_id) { - try { - for (var i = 0; i < feeds.length; i++) { - if (feeds[i].id == feed_id) - return feeds[i]; - } - - return false; - - } catch (e) { - exception_error("find_feed", e); - } -} - -function get_feed_icon(feed) { - try { - if (feed.has_icon) - return getInitParam('icons_url') + "/" + feed.id + '.ico'; - - if (feed.id == -1) - return 'images/mark_set.png'; - - if (feed.id == -2) - return 'images/pub_set.png'; - - if (feed.id == -3) - return 'images/fresh.png'; - - if (feed.id == -4) - return 'images/tag.png'; - - if (feed.id < -10) - return 'images/label.png'; - - return 'images/blank_icon.gif'; - - } catch (e) { - exception_error("get_feed_icon", e); - } -} - -function add_feed_entry(feed) { - try { - var icon_part = ""; - - icon_part = ""; - - var title = (feed.title.length > 30) ? - feed.title.substring(0, 30) + "…" : - feed.title; - - var tmp_html = "
  • " + - icon_part + title + - "
    " + "" + feed.unread + "" + - "
    " + "
  • "; - - $("feeds-content").innerHTML += tmp_html; - - - } catch (e) { - exception_error("add_feed_entry", e); - } -} - -function add_headline_entry(article, feed, no_effects) { - try { - - var icon_part = ""; - - icon_part = ""; - - - var style = ""; - - //if (!no_effects) style = "style=\"display : none\""; - - if (article.excerpt.trim() == "") - article.excerpt = __("Click to expand article."); - - var li_class = "unread"; - - var fresh_max = getInitParam("fresh_article_max_age") * 60 * 60; - var d = new Date(); - - if (d.getTime() / 1000 - article.updated < fresh_max) - li_class = "fresh"; - - //"" + - - var checkbox_part = ""; - - var date = new Date(article.updated * 1000); - - var date_part = date.toString().substring(0,21); - - var tmp_html = "
  • " + - checkbox_part + - icon_part + - "" + - article.title + "" + - "
    " + - "
    " + - article.excerpt + "
    " + - "
    "; - -/* tmp_html += "" + - feed.title + " " + " @ "; */ - - tmp_html += date_part + "
    " + - "
  • "; - - $("headlines-content").innerHTML += tmp_html; - - if (!no_effects) - window.setTimeout('article_appear(' + article.id + ')', 100); - - } catch (e) { - exception_error("add_headline_entry", e); - } -} - -function expand_feeds() { - try { - _feedlist_expanded = true; - - redraw_feedlist(last_feeds); - - } catch (e) { - exception_error("expand_feeds", e); - } -} - -function redraw_feedlist(feeds) { - try { - - $('feeds-content').innerHTML = ""; - - var limit = 10; - - if (_feedlist_expanded) limit = feeds.length; - - for (var i = 0; i < Math.min(limit, feeds.length); i++) { - add_feed_entry(feeds[i]); - } - - if (feeds.length > limit) { - $('feeds-content').innerHTML += "
  • " + - "" + - "" + - __("%d more...").replace("%d", feeds.length-10) + - "" + "
  • "; - } - - if (feeds.length == 0) { - $('feeds-content').innerHTML = - "
    " + - __("No unread feeds.") + "
    "; - } - - if (_active_feed_id) - set_selected_feed(_active_feed_id); - - } catch (e) { - exception_error("redraw_feedlist", e); - } -} - -function parse_feeds(transport) { - try { - var reply = JSON.parse(transport.responseText); - - if (!reply) return; - - var feeds = reply['feeds']; - - if (feeds) { - - feeds.sort( function (a,b) - { - if (b.unread != a.unread) - return (b.unread - a.unread); - else - if (a.title > b.title) - return 1; - else if (a.title < b.title) - return -1; - else - return 0; - }); - - var all_articles = find_feed(feeds, -4); - - update_title(all_articles.unread); - - last_feeds = feeds; - - redraw_feedlist(feeds); - } - - } catch (e) { - exception_error("parse_feeds", e); - } -} - -function parse_headlines(transport, replace, no_effects) { - try { - var reply = JSON.parse(transport.responseText); - if (!reply) return; - - var seq = reply['seq']; - - if (seq) { - if (seq != _update_seq) { - console.log("parse_headlines: wrong sequence received."); - return; - } - } else { - return; - } - - var headlines = reply['headlines']['content']; - var headlines_title = reply['headlines']['title']; - - if (headlines && headlines_title) { - - if (replace) { - $('headlines-content').innerHTML = ''; - } - - var pr = $('H-MORE-PROMPT'); - - if (pr) pr.parentNode.removeChild(pr); - - var inserted = false; - - for (var i = 0; i < headlines.length; i++) { - - if (!$('A-' + headlines[i].id)) { - add_headline_entry(headlines[i], - find_feed(last_feeds, headlines[i].feed_id), !no_effects); - - } - } - - console.log(inserted.id); - - var ids = get_visible_article_ids(); - - if (ids.length > 0) { - if (pr) { - $('headlines-content').appendChild(pr); - - } else { - $('headlines-content').innerHTML += "
  • " + - "
  • "; - } - } else { - // FIXME : display some kind of "nothing to see here" prompt here - } - -// if (replace && !no_effects) -// new Effect.Appear('headlines-content', {duration : 0.3}); - - //new Effect.Appear('headlines-content'); - } - - } catch (e) { - exception_error("parse_headlines", e); - } -} - -function init_second_stage() { - try { - new Ajax.Request("backend.php", { - parameters: "backend.php?op=rpc&method=digestinit", - onComplete: function(transport) { - parse_feeds(transport); - Element.hide("overlay"); - - document.onkeydown = hotkey_handler; - - window.setTimeout('viewfeed(-4)', 100); - _update_timeout = window.setTimeout('update()', 5*1000); - } }); - - } catch (e) { - exception_error("init_second_stage", e); - } -} - -function init() { - try { - dojo.require("dijit.Dialog"); - - new Ajax.Request("backend.php", { - parameters: {op: "rpc", method: "sanityCheck"}, - onComplete: function(transport) { - backend_sanity_check_callback(transport); - } }); - - } catch (e) { - exception_error("digest_init", e); - } -} - -function toggle_mark(img, id) { - - try { - - var query = "?op=rpc&id=" + id + "&method=mark"; - - if (!img) return; - - if (img.src.match("mark_unset")) { - img.src = img.src.replace("mark_unset", "mark_set"); - img.alt = __("Unstar article"); - query = query + "&mark=1"; - } else { - img.src = img.src.replace("mark_set", "mark_unset"); - img.alt = __("Star article"); - query = query + "&mark=0"; - } - - new Ajax.Request("backend.php", { - parameters: query, - onComplete: function(transport) { - update(); - } }); - - } catch (e) { - exception_error("toggle_mark", e); - } -} - -function toggle_pub(img, id, note) { - - try { - - var query = "?op=rpc&id=" + id + "&method=publ"; - - if (note != undefined) { - query = query + "¬e=" + param_escape(note); - } else { - query = query + "¬e=undefined"; - } - - if (!img) return; - - if (img.src.match("pub_unset") || note != undefined) { - img.src = img.src.replace("pub_unset", "pub_set"); - img.alt = __("Unpublish article"); - query = query + "&pub=1"; - - } else { - img.src = img.src.replace("pub_set", "pub_unset"); - img.alt = __("Publish article"); - query = query + "&pub=0"; - } - - new Ajax.Request("backend.php", { - parameters: query, - onComplete: function(transport) { - update(); - } }); - - } catch (e) { - exception_error("toggle_pub", e); - } -} - -function fatal_error(code, msg) { - try { - - if (code == 6) { - window.location.href = "digest.php"; - } else if (code == 5) { - window.location.href = "db-updater.php"; - } else { - - if (msg == "") msg = "Unknown error"; - - console.error("Fatal error: " + code + "\n" + - msg); - - } - - } catch (e) { - exception_error("fatalError", e); - } -} - -function fatal_error_check(transport) { - try { - if (transport.responseXML) { - var error = transport.responseXML.getElementsByTagName("error")[0]; - - if (error) { - var code = error.getAttribute("error-code"); - var msg = error.getAttribute("error-msg"); - if (code != 0) { - fatal_error(code, msg); - return false; - } - } - } - } catch (e) { - exception_error("fatal_error_check", e); - } - return true; -} - -function update_title(unread) { - try { - document.title = "Tiny Tiny RSS"; - - if (unread > 0) - document.title += " (" + unread + ")"; - - } catch (e) { - exception_error("update_title", e); - } -} - -function toggle_select_article(elem) { - try { - var article = elem.parentNode; - - if (article.hasClassName("selected")) - article.removeClassName("selected"); - else - article.addClassName("selected"); - - } catch (e) { - exception_error("toggle_select_article", e); - } -} - -function hotkey_handler(e) { - try { - - if (e.target.nodeName == "INPUT" || e.target.nodeName == "TEXTAREA") return; - - var keycode = false; - var shift_key = false; - - var cmdline = $('cmdline'); - - try { - shift_key = e.shiftKey; - } catch (e) { - - } - - if (window.event) { - keycode = window.event.keyCode; - } else if (e) { - keycode = e.which; - } - - var keychar = String.fromCharCode(keycode); - - if (keycode == 16) return; // ignore lone shift - if (keycode == 17) return; // ignore lone ctrl - - switch (keycode) { - case 27: // esc - close_article(); - break; - default: - console.log("KP: CODE=" + keycode + " CHAR=" + keychar); - } - - - } catch (e) { - exception_error("hotkey_handler", e); - } -} diff --git a/js/tt-rss.js b/js/tt-rss.js index fd02081b..348d6bbd 100644 --- a/js/tt-rss.js +++ b/js/tt-rss.js @@ -391,7 +391,7 @@ function quickMenuGo(opid) { } if (opid == "qmcDigest") { - window.location.href = "digest.php"; + window.location.href = "backend.php?op=digest"; return; } diff --git a/plugins/digest/digest.css b/plugins/digest/digest.css new file mode 100644 index 00000000..54568e3b --- /dev/null +++ b/plugins/digest/digest.css @@ -0,0 +1,337 @@ +body#ttrssDigest { + color : black; + font-family : sans-serif; + font-size : 12px; + margin : 0px; + background : url("images/tile.png"); +} + +a { + color : #0069D8; + text-decoration : none; +} + +a:hover { + color : gray; +} + +#header a, #footer a { + color : gray; +} + +#header a:hover, #footer a:hover { + color : #0069D8; +} + +#header { + font-size : 13px; + font-family : "Segoe UI", Tahoma, sans-serif; + padding : 5px 5px 5px 1.5em; + color : gray; + position : absolute; + top : 0px; + height : 30px; + left : 0px; + right : 0px; + color : #a0a0a0; +} + +#header span.title { + font-weight : bold; + font-style : italic; +} + +#header div.links { + position : absolute; + right : 1.5em; +} + +#search { + float : right; + clear : left; + +} + +#title { +} + +#latest { + padding : 5px; +} + +#content { + position : absolute; + left : 0px; + top : 30px; + right : 0px; + bottom : 0px; + -webkit-transition: left 0.2s linear, right 0.2s linear; + -moz-transition: left 0.2s linear, right 0.2s linear; + transition: left 0.2s linear, right 0.2s linear; +} + +#article { + position : absolute; + overflow : auto; + right : 0px; + width : 60%; + bottom : 0px; + top : 30px; + background : white; + z-index : -1; + opacity : 0; + -webkit-transition: opacity 0.2s linear; + -moz-transition: opacity 0.2s linear; + transition: opacity 0.2s linear; +} + +#article.visible { + opacity : 1; +} + +#article #article-content h1 { + margin : 0px 0px 10px 0px; + padding : 0px 0px 5px 0px; + font-family : "Segoe UI", Tahoma, sans-serif; + font-size : 21px; + font-weight : bold; + border-width : 0px 0px 3px 0px; + border-style : solid; + border-color : #e0e0e0; + color : gray; +} + +#article #article-content #toolbar { + border-width : 0px 0px 1px 0px; + border-color : #e0e0e0; + border-style : solid; + background : #fafafa; + font-size : 14px; + font-weight : bold; + padding : 5px 10px 5px 10px; + margin : 0px 0px 0px 0px; +} + +#article #article-content { + padding : 0px; + font-size : 16px; +} + +#article #article-content #tags { + color : #a0a0a0; +} + +#article #article-content #ops { + float : right; +} + +#article #article-content #ops img { + cursor : pointer; + margin-right : 0px; + margin-left : 10px; +} + +#article #article-content #inner { + padding : 20px; +} + +#article #article-content img { + max-width : 90%; +} + +#content.move { + left : -300px; + right : 60% +} + +#feeds { + position : absolute; + left : 0px; + width : 300px; + top : -30px; + bottom : 0px; + font-size : 14px; + overflow : auto; + border-width : 0px 3px 0px 0px; + border-color : #88b0f0; + border-style : solid; + background : #eee; +} + +#feeds ul#feeds-content img { + width : 16px; + height : 16px; + vertical-align : middle; + margin-right : 5px; +} + +#feeds ul#feeds-content div.unread-ctr { + color : #d0d0d0; + padding-left : 10px; + float : right; +} + +#feeds ul#feeds-content li { + padding : 10px; + clear : both; + cursor : pointer; + color : #303030; + white-space : nowrap; +} + +#feeds ul#feeds-content li.selected { + background : white; +} + +#feeds ul#feeds-content { + list-style-type : none; + font-weight : bold; + margin : 0px; + padding : 0px; +} + +#headlines { + font-size : 14px; + position : absolute; + left : 303px; + top : 0px; + bottom : 0px; + right : 0px; + overflow : auto; + border-width : 0px 3px 0px 0px; + border-style : solid; + border-color : #88b0f0; +} + +#headlines h1 a { + color : #684C99; +} + +#headlines ul#headlines-content .cb { + vertical-align : middle; + margin-right : 5px; + float : left; +} + +#headlines ul#headlines-content img.icon { + width : 16px; + height : 16px; + vertical-align : middle; + margin-right : 5px; + float : right; +} + +#headlines ul#headlines-content { + list-style-type : none; + color : gray; + margin : 0px; + padding : 0px; +} + +#headlines ul#headlines-content li { + margin : 0px 0px 0px 0px; + padding : 10px; + color : gray; + clear : left; + border-width : 0px 0px 1px 0px; + border-style : solid; + border-color : #e0e0e0; + background : #eee; +} + +#headlines ul#headlines-content a.title { + font-size : 14px; + font-weight : bold; + display : block; + margin-left : 21px; + position : relative; +} + +#headlines ul#headlines-content li.fresh a.title { + color : #007FFF; +} + +#headlines ul#headlines-content li.unread a.title { + color : black; + /* color : #8DB1D6; */ +} + +#headlines ul#headlines-content li.read a.title { + color : gray; +} + +#headlines ul#headlines-content li.unread, +#headlines ul#headlines-content li.fresh { + background-color : white; +} + +#headlines ul#headlines-content li.selected { + background-color : #fff7d5; + border-color : white white #e0e0e0; +} + +#headlines ul#headlines-content img#H-LOADING-IMG { + margin-left : 5px; +} + +#headlines ul#headlines-content div.excerpt { + color : #404040; + cursor : pointer; + margin-top : 5px; +} + +#headlines ul#headlines-content div.content { + color : #404040; +} + +#headlines ul#headlines-content div.content img { + max-width : 75%; +} + +#headlines ul#headlines-content div.body { + margin-left : 21px; + /*margin-left : 42px;*/ +} + +#headlines ul#headlines-content div.info { + font-size : 11px; + margin-top : 5px; +} + +#headlines ul#headlines-content div.info a { + color : gray; +} + +#overlay { + background : white; + left : 0; + top : 0; + height : 100%; + width : 100%; + z-index : 100; + position : absolute; + text-align : center; +} + +#overlay_inner { + margin : 1em; +} + +#overlay img { + vertical-align : middle; +} + +div.fatalError button { + margin-top : 5px; +} + +div.fatalError textarea { + width : 100%; + height : 100px; +} + +div.insensitive { + color : gray; +} + + diff --git a/plugins/digest/digest.js b/plugins/digest/digest.js new file mode 100644 index 00000000..522d3545 --- /dev/null +++ b/plugins/digest/digest.js @@ -0,0 +1,852 @@ +var last_feeds = []; +var init_params = {}; + +var _active_feed_id = false; +var _update_timeout = false; +var _view_update_timeout = false; +var _feedlist_expanded = false; +var _update_seq = 1; + +function article_appear(article_id) { + try { + new Effect.Appear('A-' + article_id); + } catch (e) { + exception_error("article_appear", e); + } +} + +function catchup_feed(feed_id, callback) { + try { + + var fn = find_feed(last_feeds, feed_id).title; + + if (confirm(__("Mark all articles in %s as read?").replace("%s", fn))) { + + var is_cat = ""; + + if (feed_id < 0) is_cat = "true"; // KLUDGE + + var query = "?op=rpc&method=catchupFeed&feed_id=" + + feed_id + "&is_cat=" + is_cat; + + new Ajax.Request("backend.php", { + parameters: query, + onComplete: function(transport) { + if (callback) callback(transport); + + update(); + } }); + } + + } catch (e) { + exception_error("catchup_article", e); + } +} + +function get_visible_article_ids() { + try { + var elems = $("headlines-content").getElementsByTagName("LI"); + var ids = []; + + for (var i = 0; i < elems.length; i++) { + if (elems[i].id && elems[i].id.match("A-")) { + ids.push(elems[i].id.replace("A-", "")); + } + } + + return ids; + + } catch (e) { + exception_error("get_visible_article_ids", e); + } +} + +function catchup_visible_articles(callback) { + try { + + var ids = get_visible_article_ids(); + + if (confirm(__("Mark %d displayed articles as read?").replace("%d", ids.length))) { + + var query = "?op=rpc&method=catchupSelected" + + "&cmode=0&ids=" + param_escape(ids); + + new Ajax.Request("backend.php", { + parameters: query, + onComplete: function(transport) { + if (callback) callback(transport); + + viewfeed(_active_feed_id, 0); + } }); + + } + + } catch (e) { + exception_error("catchup_visible_articles", e); + } +} + +function catchup_article(article_id, callback) { + try { + var query = "?op=rpc&method=catchupSelected" + + "&cmode=0&ids=" + article_id; + + new Ajax.Request("backend.php", { + parameters: query, + onComplete: function(transport) { + if (callback) callback(transport); + } }); + + } catch (e) { + exception_error("catchup_article", e); + } +} + +function set_selected_article(article_id) { + try { + $$("#headlines-content > li[id*=A-]").each(function(article) { + var id = article.id.replace("A-", ""); + + var cb = article.getElementsByTagName("INPUT")[0]; + + if (id == article_id) { + article.addClassName("selected"); + cb.checked = true; + } else { + article.removeClassName("selected"); + cb.checked = false; + } + + }); + + } catch (e) { + exception_error("mark_selected_feed", e); + } +} + + +function set_selected_feed(feed_id) { + try { + var feeds = $("feeds-content").getElementsByTagName("LI"); + + for (var i = 0; i < feeds.length; i++) { + if (feeds[i].id == "F-" + feed_id) + feeds[i].className = "selected"; + else + feeds[i].className = ""; + } + + _active_feed_id = feed_id; + + } catch (e) { + exception_error("mark_selected_feed", e); + } +} + +function load_more() { + try { + var pr = $("H-LOADING-IMG"); + + if (pr) Element.show(pr); + + var offset = $$("#headlines-content > li[id*=A-][class*=fresh],li[id*=A-][class*=unread]").length; + + viewfeed(false, offset, false, false, true, + function() { + var pr = $("H-LOADING-IMG"); + + if (pr) Element.hide(pr); + }); + } catch (e) { + exception_error("load_more", e); + } +} + +function update(callback) { + try { + console.log('updating feeds...'); + + window.clearTimeout(_update_timeout); + + new Ajax.Request("backend.php", { + parameters: "?op=digest&method=digestinit", + onComplete: function(transport) { + fatal_error_check(transport); + parse_feeds(transport); + set_selected_feed(_active_feed_id); + + if (callback) callback(transport); + } }); + + _update_timeout = window.setTimeout('update()', 5*1000); + } catch (e) { + exception_error("update", e); + } +} + +function remove_headline_entry(article_id) { + try { + var elem = $('A-' + article_id); + + if (elem) { + elem.parentNode.removeChild(elem); + } + + } catch (e) { + exception_error("remove_headline_entry", e); + } +} + +function view_update() { + try { + viewfeed(_active_feed_id, _active_feed_offset, false, true, true); + update(); + } catch (e) { + exception_error("view_update", e); + } +} + +function view(article_id) { + try { + $("content").addClassName("move"); + + var a = $("A-" + article_id); + var h = $("headlines"); + + setTimeout(function() { + // below or above viewport, reposition headline + if (a.offsetTop > h.scrollTop + h.offsetHeight || a.offsetTop+a.offsetHeight < h.scrollTop+a.offsetHeight) + h.scrollTop = a.offsetTop - (h.offsetHeight/2 - a.offsetHeight/2); + }, 500); + + new Ajax.Request("backend.php", { + parameters: "?op=digest&method=digestgetcontents&article_id=" + + article_id, + onComplete: function(transport) { + fatal_error_check(transport); + + var reply = JSON.parse(transport.responseText); + + if (reply) { + var article = reply['article']; + + var mark_part = ""; + var publ_part = ""; + + var tags_part = ""; + + if (article.tags.length > 0) { + tags_part = " " + __("in") + " "; + + for (var i = 0; i < Math.min(5, article.tags.length); i++) { + //tags_part += "" + + // article.tags[i] + ", "; + + tags_part += article.tags[i] + ", "; + } + + tags_part = tags_part.replace(/, $/, ""); + tags_part = "" + tags_part + ""; + + } + + if (article.marked) + mark_part = ""; + else + mark_part = ""; + + if (article.published) + publ_part = ""; + else + publ_part = ""; + + var tmp = "
    " + + "
    " + + mark_part + + publ_part + + "
    " + + "

    " + "" + + article.title + "" + "

    " + + "
    " + + tags_part + + "
    " + + article.content + "
    "; + + $("article-content").innerHTML = tmp; + $("article").addClassName("visible"); + + set_selected_article(article.id); + + catchup_article(article_id, + function() { + $("A-" + article_id).addClassName("read"); + }); + + } else { + elem.innerHTML = __("Error: unable to load article."); + } + } + }); + + + return false; + } catch (e) { + exception_error("view", e); + } +} + +function close_article() { + $("content").removeClassName("move"); + $("article").removeClassName("visible"); +} + +function viewfeed(feed_id, offset, replace, no_effects, no_indicator, callback) { + try { + + if (!feed_id) feed_id = _active_feed_id; + if (offset == undefined) offset = 0; + if (replace == undefined) replace = (offset == 0); + + _update_seq = _update_seq + 1; + + if (!offset) $("headlines").scrollTop = 0; + + var query = "backend.php?op=digest&method=digestupdate&feed_id=" + + param_escape(feed_id) + "&offset=" + offset + + "&seq=" + _update_seq; + + console.log(query); + + var img = false; + + if ($("F-" + feed_id)) { + img = $("F-" + feed_id).getElementsByTagName("IMG")[0]; + + if (img && !no_indicator) { + img.setAttribute("orig_src", img.src); + img.src = 'images/indicator_tiny.gif'; + } + } + + new Ajax.Request("backend.php", { + parameters: query, + onComplete: function(transport) { + Element.hide("overlay"); + + fatal_error_check(transport); + parse_headlines(transport, replace, no_effects); + set_selected_feed(feed_id); + _active_feed_offset = offset; + + if (img && !no_indicator) + img.src = img.getAttribute("orig_src"); + + if (callback) callback(transport); + + } }); + + } catch (e) { + exception_error("view", e); + } +} + +function find_article(articles, article_id) { + try { + for (var i = 0; i < articles.length; i++) { + if (articles[i].id == article_id) + return articles[i]; + } + + return false; + + } catch (e) { + exception_error("find_article", e); + } +} + +function find_feed(feeds, feed_id) { + try { + for (var i = 0; i < feeds.length; i++) { + if (feeds[i].id == feed_id) + return feeds[i]; + } + + return false; + + } catch (e) { + exception_error("find_feed", e); + } +} + +function get_feed_icon(feed) { + try { + if (feed.has_icon) + return getInitParam('icons_url') + "/" + feed.id + '.ico'; + + if (feed.id == -1) + return 'images/mark_set.png'; + + if (feed.id == -2) + return 'images/pub_set.png'; + + if (feed.id == -3) + return 'images/fresh.png'; + + if (feed.id == -4) + return 'images/tag.png'; + + if (feed.id < -10) + return 'images/label.png'; + + return 'images/blank_icon.gif'; + + } catch (e) { + exception_error("get_feed_icon", e); + } +} + +function add_feed_entry(feed) { + try { + var icon_part = ""; + + icon_part = ""; + + var title = (feed.title.length > 30) ? + feed.title.substring(0, 30) + "…" : + feed.title; + + var tmp_html = "
  • " + + icon_part + title + + "
    " + "" + feed.unread + "" + + "
    " + "
  • "; + + $("feeds-content").innerHTML += tmp_html; + + + } catch (e) { + exception_error("add_feed_entry", e); + } +} + +function add_headline_entry(article, feed, no_effects) { + try { + + var icon_part = ""; + + icon_part = ""; + + + var style = ""; + + //if (!no_effects) style = "style=\"display : none\""; + + if (article.excerpt.trim() == "") + article.excerpt = __("Click to expand article."); + + var li_class = "unread"; + + var fresh_max = getInitParam("fresh_article_max_age") * 60 * 60; + var d = new Date(); + + if (d.getTime() / 1000 - article.updated < fresh_max) + li_class = "fresh"; + + //"" + + + var checkbox_part = ""; + + var date = new Date(article.updated * 1000); + + var date_part = date.toString().substring(0,21); + + var tmp_html = "
  • " + + checkbox_part + + icon_part + + "" + + article.title + "" + + "
    " + + "
    " + + article.excerpt + "
    " + + "
    "; + +/* tmp_html += "" + + feed.title + " " + " @ "; */ + + tmp_html += date_part + "
    " + + "
  • "; + + $("headlines-content").innerHTML += tmp_html; + + if (!no_effects) + window.setTimeout('article_appear(' + article.id + ')', 100); + + } catch (e) { + exception_error("add_headline_entry", e); + } +} + +function expand_feeds() { + try { + _feedlist_expanded = true; + + redraw_feedlist(last_feeds); + + } catch (e) { + exception_error("expand_feeds", e); + } +} + +function redraw_feedlist(feeds) { + try { + + $('feeds-content').innerHTML = ""; + + var limit = 10; + + if (_feedlist_expanded) limit = feeds.length; + + for (var i = 0; i < Math.min(limit, feeds.length); i++) { + add_feed_entry(feeds[i]); + } + + if (feeds.length > limit) { + $('feeds-content').innerHTML += "
  • " + + "" + + "" + + __("%d more...").replace("%d", feeds.length-10) + + "" + "
  • "; + } + + if (feeds.length == 0) { + $('feeds-content').innerHTML = + "
    " + + __("No unread feeds.") + "
    "; + } + + if (_active_feed_id) + set_selected_feed(_active_feed_id); + + } catch (e) { + exception_error("redraw_feedlist", e); + } +} + +function parse_feeds(transport) { + try { + var reply = JSON.parse(transport.responseText); + + if (!reply) return; + + var feeds = reply['feeds']; + + if (feeds) { + + feeds.sort( function (a,b) + { + if (b.unread != a.unread) + return (b.unread - a.unread); + else + if (a.title > b.title) + return 1; + else if (a.title < b.title) + return -1; + else + return 0; + }); + + var all_articles = find_feed(feeds, -4); + + update_title(all_articles.unread); + + last_feeds = feeds; + + redraw_feedlist(feeds); + } + + } catch (e) { + exception_error("parse_feeds", e); + } +} + +function parse_headlines(transport, replace, no_effects) { + try { + var reply = JSON.parse(transport.responseText); + if (!reply) return; + + var seq = reply['seq']; + + if (seq) { + if (seq != _update_seq) { + console.log("parse_headlines: wrong sequence received."); + return; + } + } else { + return; + } + + var headlines = reply['headlines']['content']; + var headlines_title = reply['headlines']['title']; + + if (headlines && headlines_title) { + + if (replace) { + $('headlines-content').innerHTML = ''; + } + + var pr = $('H-MORE-PROMPT'); + + if (pr) pr.parentNode.removeChild(pr); + + var inserted = false; + + for (var i = 0; i < headlines.length; i++) { + + if (!$('A-' + headlines[i].id)) { + add_headline_entry(headlines[i], + find_feed(last_feeds, headlines[i].feed_id), !no_effects); + + } + } + + console.log(inserted.id); + + var ids = get_visible_article_ids(); + + if (ids.length > 0) { + if (pr) { + $('headlines-content').appendChild(pr); + + } else { + $('headlines-content').innerHTML += "
  • " + + "
  • "; + } + } else { + // FIXME : display some kind of "nothing to see here" prompt here + } + +// if (replace && !no_effects) +// new Effect.Appear('headlines-content', {duration : 0.3}); + + //new Effect.Appear('headlines-content'); + } + + } catch (e) { + exception_error("parse_headlines", e); + } +} + +function init_second_stage() { + try { + new Ajax.Request("backend.php", { + parameters: "backend.php?op=digest&method=digestinit", + onComplete: function(transport) { + parse_feeds(transport); + Element.hide("overlay"); + + document.onkeydown = hotkey_handler; + + window.setTimeout('viewfeed(-4)', 100); + _update_timeout = window.setTimeout('update()', 5*1000); + } }); + + } catch (e) { + exception_error("init_second_stage", e); + } +} + +function init() { + try { + dojo.require("dijit.Dialog"); + + new Ajax.Request("backend.php", { + parameters: {op: "rpc", method: "sanityCheck"}, + onComplete: function(transport) { + backend_sanity_check_callback(transport); + } }); + + } catch (e) { + exception_error("digest_init", e); + } +} + +function toggle_mark(img, id) { + + try { + + var query = "?op=rpc&id=" + id + "&method=mark"; + + if (!img) return; + + if (img.src.match("mark_unset")) { + img.src = img.src.replace("mark_unset", "mark_set"); + img.alt = __("Unstar article"); + query = query + "&mark=1"; + } else { + img.src = img.src.replace("mark_set", "mark_unset"); + img.alt = __("Star article"); + query = query + "&mark=0"; + } + + new Ajax.Request("backend.php", { + parameters: query, + onComplete: function(transport) { + update(); + } }); + + } catch (e) { + exception_error("toggle_mark", e); + } +} + +function toggle_pub(img, id, note) { + + try { + + var query = "?op=rpc&id=" + id + "&method=publ"; + + if (note != undefined) { + query = query + "¬e=" + param_escape(note); + } else { + query = query + "¬e=undefined"; + } + + if (!img) return; + + if (img.src.match("pub_unset") || note != undefined) { + img.src = img.src.replace("pub_unset", "pub_set"); + img.alt = __("Unpublish article"); + query = query + "&pub=1"; + + } else { + img.src = img.src.replace("pub_set", "pub_unset"); + img.alt = __("Publish article"); + query = query + "&pub=0"; + } + + new Ajax.Request("backend.php", { + parameters: query, + onComplete: function(transport) { + update(); + } }); + + } catch (e) { + exception_error("toggle_pub", e); + } +} + +function fatal_error(code, msg) { + try { + + if (code == 6) { + window.location.href = "digest.php"; + } else if (code == 5) { + window.location.href = "db-updater.php"; + } else { + + if (msg == "") msg = "Unknown error"; + + console.error("Fatal error: " + code + "\n" + + msg); + + } + + } catch (e) { + exception_error("fatalError", e); + } +} + +function fatal_error_check(transport) { + try { + if (transport.responseXML) { + var error = transport.responseXML.getElementsByTagName("error")[0]; + + if (error) { + var code = error.getAttribute("error-code"); + var msg = error.getAttribute("error-msg"); + if (code != 0) { + fatal_error(code, msg); + return false; + } + } + } + } catch (e) { + exception_error("fatal_error_check", e); + } + return true; +} + +function update_title(unread) { + try { + document.title = "Tiny Tiny RSS"; + + if (unread > 0) + document.title += " (" + unread + ")"; + + } catch (e) { + exception_error("update_title", e); + } +} + +function toggle_select_article(elem) { + try { + var article = elem.parentNode; + + if (article.hasClassName("selected")) + article.removeClassName("selected"); + else + article.addClassName("selected"); + + } catch (e) { + exception_error("toggle_select_article", e); + } +} + +function hotkey_handler(e) { + try { + + if (e.target.nodeName == "INPUT" || e.target.nodeName == "TEXTAREA") return; + + var keycode = false; + var shift_key = false; + + var cmdline = $('cmdline'); + + try { + shift_key = e.shiftKey; + } catch (e) { + + } + + if (window.event) { + keycode = window.event.keyCode; + } else if (e) { + keycode = e.which; + } + + var keychar = String.fromCharCode(keycode); + + if (keycode == 16) return; // ignore lone shift + if (keycode == 17) return; // ignore lone ctrl + + switch (keycode) { + case 27: // esc + close_article(); + break; + default: + console.log("KP: CODE=" + keycode + " CHAR=" + keychar); + } + + + } catch (e) { + exception_error("hotkey_handler", e); + } +} diff --git a/plugins/digest/digest.php b/plugins/digest/digest.php new file mode 100644 index 00000000..5535c322 --- /dev/null +++ b/plugins/digest/digest.php @@ -0,0 +1,100 @@ +link = $host->get_link(); + $this->host = $host; + + $host->add_handler("digest", "*", $this); + + //$host->add_handler("rpc", "digestinit", $this); + //$host->add_handler("rpc", "digestupdate", $this); + //$host->add_handler("rpc", "digestgetcontents", $this); + } + + function index() { + header("Content-type: text/html; charset=utf-8"); + + login_sequence($this->link); + + global $link; + $link = $this->link; + + require_once dirname(__FILE__) . "/digest_body.php"; + } + + /* function get_js() { + return file_get_contents(dirname(__FILE__) . "/digest.js"); + } */ + + function csrf_ignore($method) { + return in_array($method, array("index")); + } + + function before($method) { + return true; + } + + function after() { + + } + + function digestgetcontents() { + $article_id = db_escape_string($_REQUEST['article_id']); + + $result = db_query($this->link, "SELECT content,title,link,marked,published + FROM ttrss_entries, ttrss_user_entries + WHERE id = '$article_id' AND ref_id = id AND owner_uid = ".$_SESSION['uid']); + + $content = sanitize($this->link, db_fetch_result($result, 0, "content")); + $title = strip_tags(db_fetch_result($result, 0, "title")); + $article_url = htmlspecialchars(db_fetch_result($result, 0, "link")); + $marked = sql_bool_to_bool(db_fetch_result($result, 0, "marked")); + $published = sql_bool_to_bool(db_fetch_result($result, 0, "published")); + + print json_encode(array("article" => + array("id" => $article_id, "url" => $article_url, + "tags" => get_article_tags($this->link, $article_id), + "marked" => $marked, "published" => $published, + "title" => $title, "content" => $content))); + } + + function digestupdate() { + $feed_id = db_escape_string($_REQUEST['feed_id']); + $offset = db_escape_string($_REQUEST['offset']); + $seq = db_escape_string($_REQUEST['seq']); + + if (!$feed_id) $feed_id = -4; + if (!$offset) $offset = 0; + + $reply = array(); + + $reply['seq'] = $seq; + + $headlines = api_get_headlines($this->link, $feed_id, 30, $offset, + '', ($feed_id == -4), true, false, "unread", "updated DESC", 0, 0); + + $reply['headlines'] = array(); + $reply['headlines']['title'] = getFeedTitle($this->link, $feed_id); + $reply['headlines']['content'] = $headlines; + + print json_encode($reply); + } + + function digestinit() { + $tmp_feeds = api_get_feeds($this->link, -4, true, false, 0); + + $feeds = array(); + + foreach ($tmp_feeds as $f) { + if ($f['id'] > 0 || $f['id'] == -4) array_push($feeds, $f); + } + + print json_encode(array("feeds" => $feeds)); + } + +} +?> diff --git a/plugins/digest/digest.txt b/plugins/digest/digest.txt new file mode 100644 index 00000000..d94efa10 --- /dev/null +++ b/plugins/digest/digest.txt @@ -0,0 +1 @@ +Digest mode for tt-rss (tablet friendly UI) diff --git a/plugins/digest/digest_body.php b/plugins/digest/digest_body.php new file mode 100644 index 00000000..c4f51d37 --- /dev/null +++ b/plugins/digest/digest_body.php @@ -0,0 +1,81 @@ + + + + + + + Tiny Tiny RSS + + + + + + + + + + + + + + + + + + + + + + +
    +
    + + + + +
    +
    + + + +
     
    + +
    + +
    +
    +
    + +
    +
    +
    +
    + + + diff --git a/plugins/digest/images/tile.png b/plugins/digest/images/tile.png new file mode 100644 index 00000000..72f2f455 Binary files /dev/null and b/plugins/digest/images/tile.png differ