diff options
author | Bernhard Posselt <nukeawhale@gmail.com> | 2012-08-12 17:43:11 +0200 |
---|---|---|
committer | Bernhard Posselt <nukeawhale@gmail.com> | 2012-08-12 17:43:11 +0200 |
commit | 7efe48d3d7d746b62ea8daf19edf8b3542520bb7 (patch) | |
tree | 2afaa4c6ff1f33ada86fa229328e938e55fb1ea4 | |
parent | 1029b44255c02c9a03ad2ed3812dff3da47103e0 (diff) |
added an keep unread checkbox, cleaned up javascript that handled setting of item status, improved design of feedentries
-rw-r--r-- | ajax/importantitem.php | 42 | ||||
-rw-r--r-- | ajax/markitem.php | 35 | ||||
-rw-r--r-- | ajax/setitemstatus.php | 53 | ||||
-rw-r--r-- | css/news.css | 55 | ||||
-rw-r--r-- | img/inactive_star.svg | 8 | ||||
-rw-r--r-- | js/news.js | 199 | ||||
-rw-r--r-- | templates/part.items.php | 16 |
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>'; |