summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ajax/loadfeed.php18
-rw-r--r--ajax/setallitemsread.php41
-rw-r--r--ajax/setitemstatus.php2
-rw-r--r--css/news.css271
-rw-r--r--js/news.js112
-rw-r--r--templates/main.php4
-rw-r--r--templates/part.items.php20
7 files changed, 322 insertions, 146 deletions
diff --git a/ajax/loadfeed.php b/ajax/loadfeed.php
index 992e65019..020f7a706 100644
--- a/ajax/loadfeed.php
+++ b/ajax/loadfeed.php
@@ -17,19 +17,19 @@ OCP\JSON::callCheck();
$userid = OCP\USER::getUser();
-$feedid = trim($_POST['feedid']);
+$feedId = trim($_POST['feedId']);
$l = OC_L10N::get('news');
-$tmpl_items = new OCP\Template("news", "part.items");
-$tmpl_items->assign('feedid', $feedid);
-$part_items = $tmpl_items->fetchPage();
+$itemsTpl = new OCP\Template("news", "part.items");
+$itemsTpl->assign('feedid', $feedId);
+$feedItems = $itemsTpl->fetchPage();
-$tmpl_items_header = new OCP\Template("news", "part.items.header");
-$tmpl_items_header->assign('feedid', $feedid);
-$items_header = $tmpl_items_header->fetchPage();
+$feedMapper = new OCA\News\FeedMapper();
+$feed = $feedMapper->findById($feedId);
+$feedTitle = $feed->getTitle();
OCP\JSON::success(array('data' => array( 'message' => $l->t('Feed loaded!'),
- 'items_header' => $items_header,
- 'part_items' => $part_items )));
+ 'feedTitle' => $feedTitle,
+ 'feedItems' => $feedItems )));
diff --git a/ajax/setallitemsread.php b/ajax/setallitemsread.php
new file mode 100644
index 000000000..4c1876b50
--- /dev/null
+++ b/ajax/setallitemsread.php
@@ -0,0 +1,41 @@
+<?php
+/**
+* ownCloud - News app
+*
+* @author Bernhard Posselt
+* Copyright (c) 2012 - Bernhard Posselt <nukeawhale@gmail.com>
+*
+* This file is licensed under the Affero General Public License version 3 or later.
+* See the COPYING-README file
+*
+*/
+
+// Check if we are a user
+OCP\JSON::checkLoggedIn();
+OCP\JSON::checkAppEnabled('news');
+OCP\JSON::callCheck();
+
+$feedId = $_POST['feedId'];
+
+$itemMapper = new OCA\News\ItemMapper();
+$items = $itemMapper->findAllStatus($feedId, OCA\News\StatusFlag::Unread);
+
+// FIXME: maybe there is a way to set all items read in the
+// FeedMapper instead of iterating through every item and updating as
+// necessary
+foreach($items as $item){
+ $item->setRead();
+ $success = $itemMapper->update($item);
+}
+
+$l = OC_L10N::get('news');
+
+if(!$success) {
+ OCP\JSON::error(array('data' => array('message' => $l->t('Error setting all items as read.'))));
+ OCP\Util::writeLog('news','ajax/setallitemsread.php: Error setting all items as read of feed '. $feedId, OCP\Util::ERROR);
+ exit();
+}
+
+//TODO: replace the following with a real success case. see contact/ajax/createaddressbook.php for inspirations
+OCP\JSON::success(array('data' => array('feedId' => $feedId )));
+
diff --git a/ajax/setitemstatus.php b/ajax/setitemstatus.php
index 1d1849a5b..03dff7d94 100644
--- a/ajax/setitemstatus.php
+++ b/ajax/setitemstatus.php
@@ -44,7 +44,7 @@ $l = OC_L10N::get('news');
if(!$success) {
OCP\JSON::error(array('data' => array('message' => $l->t('Error marking item as read.'))));
- OCP\Util::writeLog('news','ajax/markitem.php: Error setting itemstatus to '. $status .': '.$_POST['itemid'], OCP\Util::ERROR);
+ OCP\Util::writeLog('news','ajax/setitemstatus.php: Error setting itemstatus to '. $status .': '.$_POST['itemid'], OCP\Util::ERROR);
exit();
}
diff --git a/css/news.css b/css/news.css
index 44c21e0d5..025d203f5 100644
--- a/css/news.css
+++ b/css/news.css
@@ -48,87 +48,204 @@ ul.controls li { float: left; }
/* item view */
-#rightcontent { top: 3.5em !important; padding: 0 0 0 5px; box-sizing: border-box; -moz-box-sizing: border-box; margin-top: 3.5em;}
-
-#rightcontent div.feed_controls { box-sizing: border-box; -moz-box-sizing: border-box; background: none repeat scroll 0 0 #FFFFFF; border-bottom: 1px solid #ccc; box-shadow: 0 3px 3px -3px #000000; text-align: right; overflow: hidden; position: fixed; left: 32.5em; right: 0; top: 3.5em; }
-#rightcontent div.feed_controls div.feed_title { float: left; padding-left: 10px; }
-#rightcontent div.feed_controls div.feed_title h1 { font-size: 1.7em; color: #444; padding-top: .5em; }
-
-#rightcontent #feed_items {
+#rightcontent {
+ top: 3.5em !important;
+ padding: 0 0 0 5px;
box-sizing: border-box;
-moz-box-sizing: border-box;
- overflow: auto;
- height: 100%;
-}
-
-#feed_items h1.item_title {
- clear: both;
- font-size: 1.5em;
- padding: 0 0 0 10px;
-}
-#feed_items .title_unread h1.item_title {
- font-weight: bold;
-}
-#feed_items h1.item_title a { color: #222; }
-#feed_items h1.item_title a:hover { color: #222; text-decoration: underline; }
-#feed_items .read h1.item_title { font-weight: normal;}
-#feed_items .read h1.item_title a { color: #888; }
-
-#feed_items .item_utils {
- border-top: 1px solid #ccc;
- padding: 10px 0 5px 10px;
- height: 1.8em;
- width: 100%;
-}
-#feed_items .item_utils ul li {
- display: inline-block;
- line-height: 1.5em;
- font-size: 1em;
- color: #aaa;
- float: left;
- margin-left: 10px;
- cursor: default;
-}
-#feed_items .item_utils ul li input[type=checkbox]{
- margin-left: .8em;
+ margin-top: 3.5em;
}
-#feed_items .item_utils ul.hidden_item_utils {
- display: none;
- float: right;
- margin-right: 30px;
-}
-#feed_items .news_item:hover .item_utils ul.hidden_item_utils {
- display: block;
-}
-#feed_items .news_item:hover .item_utils ul.hidden_item_utils li.keep_unread {
- cursor: pointer;
-}
-#feed_items .item_utils ul li:first-child { margin: 0}
-#feed_items .item_utils ul li.star {
- background-image: url('%appswebroot%/news/img/inactive_star.svg');
- background-repeat: no-repeat;
- background-size: 100%;
- width: 1.5em;
- height: 1.5em;
- cursor: pointer;
-}
-#feed_items .item_utils ul li.star.important,
-#feed_items .item_utils ul li.star:hover {
- background-image: url('%appswebroot%/news/img/active_star.svg');
-}
-
-
-#feed_items div.body { padding: 15px 25px 20px 25px; }
-#feed_items div.body p { line-height: 1.5; margin: 10px 0; }
-#feed_items div.body a { color: #0000ff; text-decoration: underline; }
-#feed_items div.body ul { padding-left: 15px; list-style-type: disc; }
-#feed_items div.body ul li { cursor: default; }
-#feed_items li:active { background: none; }
-#feed_items div.body pre { padding: 5px; background-color: #dadada; border: 1px solid #ccc; }
-#feed_items div.body pre code { font-family: monospace; font-size: 1.5em; }
-
-#feed_items div.rightcontentmsg { padding-left: 10px; background-color: yellow; }
+ /**
+ * View above the feeds which shows the feed title
+ * and the controls
+ */
+ #rightcontent div.feed_controls {
+ box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ background: none repeat scroll 0 0 #FFFFFF;
+ border-bottom: 1px solid #ccc;
+ box-shadow: 0 3px 3px -3px #000000;
+ text-align: right; overflow: hidden;
+ position: fixed;
+ left: 32.5em;
+ right: 0;
+ top: 3.5em;
+ }
+
+ #rightcontent div.feed_controls div.feed_title {
+ float: left;
+ padding-left: 10px;
+ }
+
+ #rightcontent div.feed_controls div.feed_title h1 {
+ font-size: 1.7em;
+ color: #444;
+ padding-top: .5em;
+ }
+
+ /**
+ * Area below the feed title and controls
+ */
+ #rightcontent #feed_items {
+ box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ overflow: auto;
+ height: 100%;
+ }
+
+ #rightcontent #feed_items li:active {
+ background: none;
+ }
+
+ /**
+ * Rules for a single feed item
+ */
+ .feed_item {
+ border-top: 1px solid #ccc;
+ min-height: 100px;
+ }
+
+ /**
+ * Utils panel
+ */
+ .utils {
+ height: 2em;
+ margin: 0;
+ padding: 0.6em 0.5em 0.5em 0.5em;
+ background-image: linear-gradient(top, rgb(238,238,238) 0%, rgb(255,255,255) 100%);
+ background-image: -o-linear-gradient(top, rgb(238,238,238) 0%, rgb(255,255,255) 100%);
+ background-image: -moz-linear-gradient(top, rgb(238,238,238) 0%, rgb(255,255,255) 100%);
+ background-image: -webkit-linear-gradient(top, rgb(238,238,238) 0%, rgb(255,255,255) 100%);
+ background-image: -ms-linear-gradient(top, rgb(238,238,238) 0%, rgb(255,255,255) 100%);
+ }
+
+ /**
+ * Primary feed utils which are always shown
+ */
+ .feed_item .primary_item_utils {
+ float: left;
+ }
+
+ .feed_item .primary_item_utils li {
+ display: inline-block;
+ line-height: 1.5em;
+ font-size: 1em;
+ color: #aaa;
+ float: left;
+ margin-left: ;
+ cursor: default;
+ }
+
+ .feed_item .primary_item_utils li:first-child { margin: 0}
+ .feed_item .primary_item_utils li.star {
+ background-image: url('%appswebroot%/news/img/inactive_star.svg');
+ background-repeat: no-repeat;
+ background-size: 100%;
+ width: 1.5em;
+ height: 1.5em;
+ cursor: pointer;
+ }
+
+ .feed_item .primary_item_utils li.star.important,
+ .feed_item .primary_item_utils li.star:hover {
+ background-image: url('%appswebroot%/news/img/active_star.svg');
+ }
+
+ /**
+ * Secondary feed items which are only shown on hover
+ */
+ .feed_item .secondary_item_utils {
+ float: right;
+ color: #aaa;
+ }
+ /*
+ .feed_item:hover .secondary_item_utils {
+ display: block;
+ }*/
+
+ .feed_item:hover .secondary_item_utils li.keep_unread {
+ cursor: pointer;
+ }
+
+ .feed_item .secondary_item_utils li input[type=checkbox]{
+ margin-left: .8em;
+ }
+
+ /**
+ * Feed title
+ */
+ .feed_item h1.item_title {
+ font-size: 1.5em;
+ margin: 0 0 0 1.6em;
+ font-weight: bold;
+ }
+
+ .feed_item h1.item_title a {
+ color: #222;
+ }
+ .feed_item h1.item_title a:hover {
+ color: #222;
+ text-decoration: underline;
+ }
+
+ /**
+ * Feed title when read
+ */
+ .feed_item.read h1.item_title {
+ font-weight: normal;
+ }
+
+ .feed_item.read h1.item_title a {
+ color: #888;
+ }
+
+ /**
+ * Author of the feed
+ */
+ .feed_item h2.item_author {
+ color: #aaa;
+ margin-left: 2.5em;
+ }
+
+
+ /**
+ * Body of the feed item
+ */
+ .feed_item div.body {
+ padding: .5em 2.5em 2em 2.5em;
+ }
+
+ .feed_item div.body p {
+ line-height: 1.5;
+ margin: 10px 0;
+ }
+
+ .feed_item div.body a {
+ color: #0000ff;
+ text-decoration: underline;
+ }
+
+ .feed_item div.body ul {
+ padding-left: 15px;
+ list-style-type: disc;
+ }
+
+ .feed_item div.body ul li {
+ cursor: default;
+ }
+
+ .feed_item div.body pre {
+ padding: 5px;
+ background-color: #dadada;
+ border: 1px solid #ccc;
+ }
+
+ .feed_item div.body pre code {
+ font-family: monospace;
+ font-size: 1.5em;
+ }
+
/* dialog/menues */
diff --git a/js/news.js b/js/news.js
index 22eb7195a..96a8fe56d 100644
--- a/js/news.js
+++ b/js/news.js
@@ -175,23 +175,35 @@ News={
});
return false;
},
- setAllItemsRead:function() {
- $("#feed_items li:not(.read)").each(function(){
- var itemId = $(this).data('id');
- var handler = new News.ItemStatusHandler(itemId);
- handler.setRead(true);
+ setAllItemsRead:function(feedId) {
+ $.post(OC.filePath('news', 'ajax', 'setallitemsread.php'), { 'feedId' : feedId }, function(jsonData) {
+ if(jsonData.status == 'success'){
+ // mark ui items as read
+ $("#feed_items .feed_item:not(.read)").each(function(){
+ $(this).addClass('read');
+ });
+
+ var $feedItemCounter = $('li.feed[data-id="'+feedId+'"]').find('.unreaditemcounter');
+ $feedItemCounter.removeClass('nonzero').addClass('zero');
+ $feedItemCounter.empty();
+ } else {
+ OC.dialogs.alert(t('news', 'Error while loading the feed'), t('news', 'Error'));
+ }
});
},
- load:function(feedid) {
- $.post(OC.filePath('news', 'ajax', 'loadfeed.php'),{'feedid':feedid},function(jsondata) {
- if(jsondata.status == 'success'){
- var rightcontent = $('div.rightcontent');
- rightcontent.empty();
- rightcontent.attr('data-id', feedid);
- rightcontent.html(jsondata.data.items_header + jsondata.data.part_items);
+ load:function(feedId) {
+ $.post(OC.filePath('news', 'ajax', 'loadfeed.php'), { 'feedId' : feedId }, function(jsonData) {
+ if(jsonData.status == 'success'){
+ var $rightContent = $(".rightcontent");
+ $rightContent.attr('data-id', feedId);
+ var $feedItems = $('#feed_items');
+ $feedItems.empty();
+ $feedItems.html(jsonData.data.feedItems);
+ var $feedTitle = $(".feed_controls .feed_title h1");
+ $feedTitle.html('ยป ' + jsonData.data.feedTitle);
$('li#selected_feed').attr('id', '');
- $('li.feed[data-id="' + feedid + '"]').attr('id', 'selected_feed');
+ $('li.feed[data-id="' + feedId + '"]').attr('id', 'selected_feed');
transformCollapsableTrigger();
bindItemEventListeners();
@@ -244,10 +256,10 @@ News={
// TODO: safe this on the server
switch(value){
case 'all':
- $("#feed_items li").show();
+ $("#feed_items .feed_item").show();
break;
case 'newest':
- $("#feed_items li.title_read").hide();
+ $("#feed_items .feed_item.read").hide();
break;
default:
break;
@@ -259,8 +271,8 @@ News={
ItemStatusHandler: function(itemId){
var _itemId = itemId;
var _$currentItem = $('#feed_items li[data-id="' + itemId + '"]');
- var _$currentItemStar = _$currentItem.children('.item_utils').children('ul').children('.star');
- var _$currentItemKeepUnread = _$currentItem.children('.item_utils').children('.hidden_item_utils').children('.keep_unread').children('input[type=checkbox]');
+ var _$currentItemStar = _$currentItem.children('.utils').children('.primary_item_utils').children('.star');
+ var _$currentItemKeepUnread = _$currentItem.children('.utils').children('.secondary_item_utils').children('.keep_unread').children('input[type=checkbox]');
var _feedId = _$currentItem.data('feedid');
var _read = _$currentItem.hasClass('read');
var _important = _$currentItemStar.hasClass('important');
@@ -342,18 +354,17 @@ News={
if (oldcount <= 1) {
counterplace.removeClass('nonzero').addClass('zero');
title.removeClass('nonzero').addClass('zero');
- }
- else {
- counterplace.append(--oldcount);
+ } else {
+ counterplace.html(--oldcount);
}
} else {
_$currentItem.removeClass('read');
- if (oldcount >= 1) {
+ if (oldcount === '') {
counterplace.removeClass('zero').addClass('nonzero');
title.removeClass('zero').addClass('nonzero');
- }
- else {
- counterplace.append(--oldcount);
+ counterplace.html(1);
+ } else {
+ counterplace.html(++oldcount);
}
}
@@ -439,26 +450,9 @@ function setupFeedList() {
*/
function bindItemEventListeners(){
- // mark items whose title was hid under the top edge as read
- // when the bottom is reached, mark all items as read
- $('#feed_items').scroll(function(){
- var boxHeight = $(this).height();
- var scrollHeight = $(this).prop('scrollHeight');
- var scrolled = $(this).scrollTop() + boxHeight;
-
- $(this).children('ul').children('li:not(.read)').each(function(){
- var itemOffset = $(this).position().top;
- if(itemOffset <= 0 || scrolled >= scrollHeight){
- var itemId = $(this).data('id');
- var handler = new News.ItemStatusHandler(itemId);
- handler.setRead(true);
- }
- })
- });
-
// single hover on item should mark it as read too
$('#feed_items h1.item_title a').click(function(){
- var $item = $(this).parent().parent('.news_item');
+ var $item = $(this).parent().parent('.feed_item');
var itemId = $item.data('id');
var handler = new News.ItemStatusHandler(itemId);
handler.setRead(true);
@@ -466,7 +460,7 @@ function bindItemEventListeners(){
// mark or unmark as important
$('#feed_items li.star').click(function(){
- var $item = $(this).parent().parent().parent('.news_item');
+ var $item = $(this).parent().parent().parent('.feed_item');
var itemId = $item.data('id');
var handler = new News.ItemStatusHandler(itemId);
handler.toggleImportant();
@@ -474,7 +468,7 @@ function bindItemEventListeners(){
// toggle logic for the keep unread handler
$('#feed_items .keep_unread').click(function(){
- var $item = $(this).parent().parent().parent('.news_item');
+ var $item = $(this).parent().parent().parent('.feed_item');
var itemId = $item.data('id');
var handler = new News.ItemStatusHandler(itemId);
handler.toggleKeepUnread();
@@ -482,12 +476,8 @@ function bindItemEventListeners(){
// bind the mark all as read button
$('#mark_all_as_read').click(function(){
- News.Feed.setAllItemsRead();
- });
-
- // filter for newest or all items
- $('#feed_filter').change(function(){
- News.Feed.filter($(this).val());
+ var feedId = $('.rightcontent').data('id');
+ News.Feed.setAllItemsRead(feedId);
});
}
@@ -523,6 +513,28 @@ $(document).ready(function(){
bindItemEventListeners();
+ // filter for newest or all items
+ $('#feed_filter').change(function(){
+ News.Feed.filter($(this).val());
+ });
+
+ // mark items whose title was hid under the top edge as read
+ // when the bottom is reached, mark all items as read
+ $('#feed_items').scroll(function(){
+ var boxHeight = $(this).height();
+ var scrollHeight = $(this).prop('scrollHeight');
+ var scrolled = $(this).scrollTop() + boxHeight;
+
+ $(this).children('ul').children('.feed_item:not(.read)').each(function(){
+ var itemOffset = $(this).position().top;
+ if(itemOffset <= 0 || scrolled >= scrollHeight){
+ var itemId = $(this).data('id');
+ var handler = new News.ItemStatusHandler(itemId);
+ handler.setRead(true);
+ }
+ })
+ });
+
});
$(document).click(function(event) {
diff --git a/templates/main.php b/templates/main.php
index e02a29277..5c066e599 100644
--- a/templates/main.php
+++ b/templates/main.php
@@ -35,7 +35,9 @@ if ($_['feedid']){
<div id="rightcontent" class="rightcontent" data-id="<?php echo $_['feedid']; ?>">
<?php
echo $this->inc("part.items.header");
- echo $this->inc("part.items");
+ echo '<div id="feed_items">';
+ echo $this->inc("part.items");
+ echo '</div>';
?>
<div id="appsettings" class="popup bottomleft hidden"></div>
diff --git a/templates/part.items.php b/templates/part.items.php
index 4099bac34..e481bd2d2 100644
--- a/templates/part.items.php
+++ b/templates/part.items.php
@@ -5,7 +5,6 @@ $feedid = isset($_['feedid']) ? $_['feedid'] : '';
$itemmapper = new OCA\News\ItemMapper();
$items = $itemmapper->findAll($feedid);
-echo '<div id="feed_items">';
echo '<ul>';
foreach($items as $item) {
@@ -23,20 +22,25 @@ foreach($items as $item) {
$startTitle = $l->t('Mark as important');
}
- echo '<li class="news_item ' . $newsItemClass .'" data-id="' . $item->getId() . '" data-feedid="' . $feedid . '">';
- echo '<div class="item_utils">';
- echo '<ul>';
+ echo '<li class="feed_item ' . $newsItemClass .'" data-id="' . $item->getId() . '" data-feedid="' . $feedid . '">';
+
+ echo '<div class="utils">';
+ echo '<ul class="primary_item_utils">';
echo '<li class="star ' . $starClass . '" title="' . $startTitle . '"></li>';
- echo '<li>' . parse_url($item->getUrl())['host'] . '</li>';
echo '</ul>';
- echo '<ul class="hidden_item_utils">';
+
+ echo '<ul class="secondary_item_utils">';
echo '<li class="keep_unread">' . $l->t('Keep unread') . '<input type="checkbox" /></li>';
echo '</ul>';
echo '</div>';
- echo '<h1 class="item_title"><a target="_blank" href="' . $item->getUrl() . '">' . $item->getTitle() . '</a></h1>';
+
+ echo '<h1 class="item_title"><a target="_blank" href="' . $item->getUrl() . '">' . $item->getTitle() . '</a></h1>';
+
+ echo '<h2 class="item_author">' . $l->t('from') . ' ' . parse_url($item->getUrl())['host'] . '</h2>';
+
echo '<div class="body">' . $item->getBody() . '</div>';
+
echo '</li>';
}
echo '</ul>';
-echo '</div>';