summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ajax/importantitem.php42
-rw-r--r--ajax/markitem.php35
-rw-r--r--ajax/setitemstatus.php53
-rw-r--r--css/news.css55
-rw-r--r--img/inactive_star.svg8
-rw-r--r--js/news.js199
-rw-r--r--templates/part.items.php16
7 files changed, 247 insertions, 161 deletions
diff --git a/ajax/importantitem.php b/ajax/importantitem.php
deleted file mode 100644
index 72a07f747..000000000
--- a/ajax/importantitem.php
+++ /dev/null
@@ -1,42 +0,0 @@
-<?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();
-
-$itemId = $_POST['itemId'];
-$isImportant = $_POST['isImportant'];
-
-$itemMapper = new OCA\News\ItemMapper();
-$item = $itemMapper->find($itemId);
-
-if($isImportant){
- $item->setImportant();
-} else {
- $item->setUnimportant();
-}
-
-$success = $itemMapper->update($item);
-
-$l = OC_L10N::get('news');
-
-if(!$success) {
- OCP\JSON::error(array('data' => array('message' => $l->t('Error marking item as important.'))));
- OCP\Util::writeLog('news','ajax/importantitem.php: Error marking item as important: '.$_POST['itemId'], 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('itemId' => $itemId)));
-
diff --git a/ajax/markitem.php b/ajax/markitem.php
deleted file mode 100644
index a6efc8521..000000000
--- a/ajax/markitem.php
+++ /dev/null
@@ -1,35 +0,0 @@
-<?php
-/**
-* ownCloud - News app
-*
-* @author Alessandro Cosentino
-* Copyright (c) 2012 - Alessandro Cosentino <cosenal@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();
-
-$itemid = $_POST['itemid'];
-
-$itemmapper = new OCA\News\ItemMapper();
-$item = $itemmapper->find($itemid);
-$item->setRead();
-$success = $itemmapper->update($item);
-
-$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 marking item as read: '.$_POST['itemid'], 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('itemid' => $itemid )));
-
diff --git a/ajax/setitemstatus.php b/ajax/setitemstatus.php
new file mode 100644
index 000000000..1d1849a5b
--- /dev/null
+++ b/ajax/setitemstatus.php
@@ -0,0 +1,53 @@
+<?php
+/**
+* ownCloud - News app
+*
+* @author Alessandro Cosentino
+* Copyright (c) 2012 - Alessandro Cosentino <cosenal@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();
+
+$itemId = $_POST['itemId'];
+$status = $_POST['status'];
+
+$itemMapper = new OCA\News\ItemMapper();
+$item = $itemMapper->find($itemId);
+
+switch ($status) {
+ case 'read':
+ $item->setRead();
+ break;
+ case 'unread':
+ $item->setUnread();
+ break;
+ case 'important':
+ $item->setImportant();
+ break;
+ case 'unimportant':
+ $item->setUnimportant();
+ break;
+ default:
+ break;
+}
+
+$success = $itemMapper->update($item);
+
+$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);
+ exit();
+}
+
+//TODO: replace the following with a real success case. see contact/ajax/createaddressbook.php for inspirations
+OCP\JSON::success(array('data' => array('itemId' => $itemId )));
+
diff --git a/css/news.css b/css/news.css
index 1b2c0fbe3..44c21e0d5 100644
--- a/css/news.css
+++ b/css/news.css
@@ -61,27 +61,56 @@ ul.controls li { float: left; }
height: 100%;
}
-#feed_items h1.item_title { }
-#feed_items .title_unread h1.item_title { font-weight: bold; border-bottom: 1px solid #222; }
-#feed_items .title_unread h1.item_title a { color: #222; }
-#feed_items .title_unread h1.item_title,
-#feed_items .title_read h1.item_title { padding: 15px 10px 10px 10px; font-size: 1.5em; }
-#feed_items .title_read h1.item_title { font-weight: normal; border-bottom: 1px solid #ccc; }
-#feed_items .title_read h1.item_title a { color: #888; }
-#feed_items .title_read a:hover, #feed_items .title_unread a:hover { text-decoration: underline; }
+#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;
- padding: 15px 10px 10px;
+ margin-left: 10px;
+ cursor: default;
+}
+#feed_items .item_utils ul li input[type=checkbox]{
+ margin-left: .8em;
+}
+#feed_items .item_utils ul.hidden_item_utils {
+ display: none;
+ float: right;
+ margin-right: 30px;
}
-#feed_items .item_utils ul {}
-#feed_items .item_utils ul li { display: inline-block; }
+#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%;
- height: 1.5em;
width: 1.5em;
+ height: 1.5em;
+ cursor: pointer;
}
#feed_items .item_utils ul li.star.important,
#feed_items .item_utils ul li.star:hover {
@@ -89,7 +118,7 @@ ul.controls li { float: left; }
}
-#feed_items div.body { padding: 15px 25px 10px 25px; }
+#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; }
diff --git a/img/inactive_star.svg b/img/inactive_star.svg
index 5273fcd86..d2dbb0bd9 100644
--- a/img/inactive_star.svg
+++ b/img/inactive_star.svg
@@ -14,7 +14,7 @@
id="svg2"
version="1.1"
inkscape:version="0.48.3.1 r9886"
- sodipodi:docname="New document 1">
+ sodipodi:docname="inactive_star.svg">
<defs
id="defs4" />
<sodipodi:namedview
@@ -25,8 +25,8 @@
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="2.8"
- inkscape:cx="108.52005"
- inkscape:cy="134.37797"
+ inkscape:cx="44.591479"
+ inkscape:cy="133.66368"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
@@ -47,7 +47,7 @@
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- <dc:title></dc:title>
+ <dc:title />
</cc:Work>
</rdf:RDF>
</metadata>
diff --git a/js/news.js b/js/news.js
index 2be7499ed..22eb7195a 100644
--- a/js/news.js
+++ b/js/news.js
@@ -175,59 +175,11 @@ News={
});
return false;
},
- markItem:function(itemid, feedid) {
- var currentitem = $('#feed_items [data-id="' + itemid + '"][data-feedid="' + feedid + '"]');
- if (currentitem.hasClass('title_unread')) {
- $.post(OC.filePath('news', 'ajax', 'markitem.php'),{'itemid':itemid},function(jsondata){
- if(jsondata.status == 'success'){
- currentitem.removeClass('title_unread');
- currentitem.addClass('title_read');
-
- // decrement counter
- var counterplace = $('li.feed[data-id="'+feedid+'"]').find('.unreaditemcounter');
- var title = $('li.feed[data-id="'+feedid+'"] > a');
- var oldcount = counterplace.html();
- counterplace.empty();
- if (oldcount <= 1) {
- counterplace.removeClass('nonzero').addClass('zero');
- title.removeClass('nonzero').addClass('zero');
- }
- else {
- counterplace.append(--oldcount);
- }
- //set a timeout for this
- }
- else{
- OC.dialogs.alert(jsondata.data.message, t('news', 'Error'));
- }
- })
- };
- },
- markAllItems:function() {
- $("#feed_items li.title_unread").each(function(){
+ setAllItemsRead:function() {
+ $("#feed_items li:not(.read)").each(function(){
var itemId = $(this).data('id');
- var feedId = $(this).data('feedid');
- News.Feed.markItem(itemId, feedId);
- });
- },
- setImportant:function(isImportant, itemId, feedId){
- var $currentItem = $('#feed_items [data-id="' + itemId + '"][data-feedid="' + feedId + '"]');
- var $currentStar = $currentItem.children('.item_utils').children('ul').children('li.star');
- data = {
- isImportant: isImportant,
- itemId: itemId,
- feedId: feedId
- };
- $.post(OC.filePath('news', 'ajax', 'importantitem.php'), data, function(jsondata){
- if(jsondata.status == 'success'){
- if(isImportant){
- $currentStar.removeClass('important');
- } else {
- $currentStar.addClass('important');
- }
- } else{
- OC.dialogs.alert(jsondata.data.message, t('news', 'Error'));
- }
+ var handler = new News.ItemStatusHandler(itemId);
+ handler.setRead(true);
});
},
load:function(feedid) {
@@ -302,7 +254,123 @@ News={
}
}
- }
+ },
+ // this handler handles changes in the ui when the itemstatus changes
+ 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 _feedId = _$currentItem.data('feedid');
+ var _read = _$currentItem.hasClass('read');
+ var _important = _$currentItemStar.hasClass('important');
+ var _keepUnread = _$currentItemKeepUnread.prop('checked');
+
+ /**
+ * Switches important items to unimportant and vice versa
+ */
+ var _toggleImportant = function(){
+ if(_important){
+ status = 'unimportant';
+ } else {
+ status = 'important';
+ }
+
+ var data = {
+ itemId: itemId,
+ status: status
+ };
+
+ $.post(OC.filePath('news', 'ajax', 'setitemstatus.php'), data, function(jsondata){
+ if(jsondata.status == 'success'){
+ if(_important){
+ _$currentItemStar.removeClass('important');
+ } else {
+ _$currentItemStar.addClass('important');
+ }
+ } else{
+ OC.dialogs.alert(jsondata.data.message, t('news', 'Error'));
+ }
+ });
+ };
+
+ /**
+ * Toggles an item as "keep unread". This prevents all handlers to mark it as unread
+ * except the current one
+ */
+ var _toggleKeepUnread = function(){
+ if(_keepUnread){
+ _$currentItemKeepUnread.prop("checked", false);
+ } else {
+ _$currentItemKeepUnread.prop("checked", true);
+ _setRead(false);
+ }
+ };
+
+ /**
+ * Sets the current item as read or unread
+ * @param read true sets the item to read, false to unread
+ */
+ var _setRead = function(read){
+ var status;
+
+ // if we already have the status, do nothing
+ if(read === _read) return;
+ // check if the keep unread flag was set
+ if(read && _keepUnread) return;
+
+ if(read){
+ status = 'read';
+ } else {
+ status = 'unread';
+ }
+
+ var data = {
+ itemId: itemId,
+ status: status
+ };
+
+ $.post(OC.filePath('news', 'ajax', 'setitemstatus.php'), data, function(jsonData){
+ if(jsonData.status == 'success'){
+ var counterplace = $('li.feed[data-id="'+_feedId+'"]').find('.unreaditemcounter');
+ var title = $('li.feed[data-id="'+_feedId+'"] > a');
+ var oldcount = counterplace.html();
+ counterplace.empty();
+
+ if(read){
+ _$currentItem.addClass('read');
+ if (oldcount <= 1) {
+ counterplace.removeClass('nonzero').addClass('zero');
+ title.removeClass('nonzero').addClass('zero');
+ }
+ else {
+ counterplace.append(--oldcount);
+ }
+ } else {
+ _$currentItem.removeClass('read');
+ if (oldcount >= 1) {
+ counterplace.removeClass('zero').addClass('nonzero');
+ title.removeClass('zero').addClass('nonzero');
+ }
+ else {
+ counterplace.append(--oldcount);
+ }
+ }
+
+ } else {
+ OC.dialogs.alert(jsonData.data.message, t('news', 'Error'));
+ }
+ })
+
+ };
+
+ // set public methods
+ this.setRead = function(read){ _setRead(read); }
+ this.isRead = function(){ return _read; }
+ this.toggleImportant = function(){ _toggleImportant(); }
+ this.toggleKeepUnread = function(){ _toggleKeepUnread(); }
+ },
+
}
function transformCollapsableTrigger() {
@@ -378,12 +446,12 @@ function bindItemEventListeners(){
var scrollHeight = $(this).prop('scrollHeight');
var scrolled = $(this).scrollTop() + boxHeight;
- $(this).children('ul').children('li.title_unread').each(function(){
+ $(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 feedId = $(this).data('feedid');
- News.Feed.markItem(itemId, feedId);
+ var handler = new News.ItemStatusHandler(itemId);
+ handler.setRead(true);
}
})
});
@@ -392,22 +460,29 @@ function bindItemEventListeners(){
$('#feed_items h1.item_title a').click(function(){
var $item = $(this).parent().parent('.news_item');
var itemId = $item.data('id');
- var feedId = $item.data('feedid');
- News.Feed.markItem(itemId, feedId);
+ var handler = new News.ItemStatusHandler(itemId);
+ handler.setRead(true);
})
// mark or unmark as important
$('#feed_items li.star').click(function(){
- var important = $(this).hasClass('important');
var $item = $(this).parent().parent().parent('.news_item');
var itemId = $item.data('id');
- var feedId = $item.data('feedid');
- News.Feed.setImportant(important, itemId, feedId);
+ var handler = new News.ItemStatusHandler(itemId);
+ handler.toggleImportant();
+ })
+
+ // toggle logic for the keep unread handler
+ $('#feed_items .keep_unread').click(function(){
+ var $item = $(this).parent().parent().parent('.news_item');
+ var itemId = $item.data('id');
+ var handler = new News.ItemStatusHandler(itemId);
+ handler.toggleKeepUnread();
})
// bind the mark all as read button
$('#mark_all_as_read').click(function(){
- News.Feed.markAllItems();
+ News.Feed.setAllItemsRead();
});
// filter for newest or all items
diff --git a/templates/part.items.php b/templates/part.items.php
index 7334fa35a..4099bac34 100644
--- a/templates/part.items.php
+++ b/templates/part.items.php
@@ -10,9 +10,9 @@ echo '<ul>';
foreach($items as $item) {
if($item->isRead()){
- $newsItemClass = "title_read";
+ $newsItemClass = "read";
} else {
- $newsItemClass = "title_unread";
+ $newsItemClass = "";
}
if($item->isImportant()){
@@ -24,9 +24,15 @@ foreach($items as $item) {
}
echo '<li class="news_item ' . $newsItemClass .'" data-id="' . $item->getId() . '" data-feedid="' . $feedid . '">';
- echo '<div class="item_utils"><ul>';
- echo '<li class="star ' . $starClass . '" title="' . $startTitle . '"></li>';
- echo '</ul></div>';
+ echo '<div class="item_utils">';
+ echo '<ul>';
+ 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 '<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 '<div class="body">' . $item->getBody() . '</div>';
echo '</li>';