From be192931ce450ea6c5310bf858517ef391a2a2b3 Mon Sep 17 00:00:00 2001 From: Bernhard Posselt Date: Thu, 30 Aug 2012 19:31:09 +0200 Subject: merged --- css/news.css | 357 +++++++++------------- index.php | 2 + js/main.js | 96 ++++++ js/menu.js | 683 ++++++++++++++---------------------------- js/news.js | 50 +--- templates/main.php | 12 +- templates/part.feeds.php | 47 +-- templates/part.listfeed.php | 17 +- templates/part.listfolder.php | 23 +- 9 files changed, 515 insertions(+), 772 deletions(-) create mode 100644 js/main.js diff --git a/css/news.css b/css/news.css index 595d13fdf..730fa6039 100644 --- a/css/news.css +++ b/css/news.css @@ -59,286 +59,222 @@ div.add_parentfolder { } /* feed/folder list */ -#leftcontent { +#leftcontent_news { width: 20em; margin: 0; - z-index: 0; + height: 100%; position: relative; overflow: hidden; - top: 0; - bottom: 0; + border-right: 1px solid #ccc; + background-color: #f8f8f8; + box-sizing: border-box; + -moz-box-sizing: border-box; } -#feeds { +#feed_wrapper { background-color: #f8f8f8; - position: absolute; + position: relative; top: 0; - bottom: 2.8em; - left: 0; - right: 0; + height: 100%; + padding-bottom: 2.8em; box-sizing: border-box; -moz-box-sizing: border-box; } +#feeds { + height: 100%; + overflow: auto; +} + #feeds > ul { height: 100%; - overflow: auto; + overflow-x: hidden; } - + .dnd_over { - -moz-transition: background-color 200ms ease 0s; - transition: background-color 200ms ease 0s; - background-color: #d0d0d0! important; + -moz-transition: padding-bottom 500ms ease 0s; + transition: padding-bottom 500ms ease 0s; + } + + #feeds > ul.dnd_over { + } .dnd_over > ul { - padding-bottom: 2.5em; - -moz-transition: padding-bottom 500ms ease 0s; - transition: padding-bottom 500ms ease 0s; + padding-bottom: 2.5em! important; + } + #feeds > ul ul.dnd_over { + padding-bottom: 2.5em !important; + } - #feeds .folder { - box-sizing: border-box; - -moz-box-sizing: border-box; - padding: .5em 0 .5em 2.5em !important; - background-color: #dfdfdf !important; - font-weight: bold ; - border-bottom: 1px solid #bbb !important; - position: relative; - z-index: 1; + .all_read { + font-weight: normal; } - #feeds .folder a { - float: none; - display: inline-block; - position: relative; + + #feeds .buttons { + position: absolute; + right: 0; + top: 0; + bottom: 0; + display: none; + } + + #feeds .buttons button { + margin: .65em .3em 0 0; + background-position: center; + background-repeat: no-repeat; } - #feeds .folder:hover { - background-color: #d0d0d0 !important; - -moz-transition: background-color 200ms ease 0s; - transition: background-color 200ms ease 0s; + #feeds li:hover > .buttons { + display: block; } - #feeds .subscriptions, #feeds .subscriptions:hover { - background-image: url('%appswebroot%/news/img/rss.svg'); - background-repeat: no-repeat; - background-size: 16px 16px; - background-position: .8em center; + #feeds .buttons button.feeds_delete { + background-image: url('%webroot%/core/img/actions/delete.svg'); + } + + #feeds .buttons button.feeds_edit { + background-image: url('%webroot%/core/img/actions/rename.svg'); + } + + #feeds .buttons button.feeds_markread { + background-image: url('%appswebroot%/news/img/mark_read.svg'); + } + + #feeds button.collapsable_trigger { + position: absolute; + left: .5em; + top: .4em; + background: none; + background-image: url('%webroot%/core/img/actions/triangle-s.svg'); + border: none; + border-radius: 0; + outline: none !important; + box-shadow: none; + -moz-box-shadow: none; + display: none; } - #feeds .starred, #feeds .starred:hover { - background-image: url('%appswebroot%/news/img/starred.svg'); - background-repeat: no-repeat; - background-size: 16px 16px; - background-position: .8em center; - + #feeds button.collapsable_trigger.triggered { + -moz-transform: rotate(-90deg); + transform: rotate(-90deg); } - #feeds .subscriptions a, #feeds .starred a { - display: inline-block; - width: 75%; + #feeds .folder.collapsable:hover button.collapsable_trigger { + display: block; } - #feeds li.feed { - position: relative; + #feeds li { + border-bottom: 1px solid #bbb; + padding: 0 .5em; + background-color: #dfdfdf; + font-weight: bold ; box-sizing: border-box; -moz-box-sizing: border-box; - border-bottom: 1px solid #ccc; - padding-left: 2.5em; - -moz-transition: background-color 200ms ease 0s; - transition: background-color 200ms ease 0s; - background-color: #f1f1f1; - z-index: 1; - background-size:16px 16px; - background-repeat: no-repeat; - background-position: .8em center; + width: 100%; + position: relative; } - - #feeds li.feed a { - display: inline-block; - overflow: hidden; - text-overflow: ellipsis; - text-align: left; - width: 85%; - font-weight: bold; - } - - #feeds li.feed a.all_read, #feeds .all_read { - font-weight: normal; - } - #feeds li#selected_feed { - background-color: #ffffff !important; - font-style: oblique; - } + #feeds li#selected_feed { + background-color: #ffffff !important; + font-style: oblique; + } - #feeds li.feed.updating { - padding-right: 21px; - background-image: url('%webroot%/core/img/loader.gif'); + #feeds li a.title { + box-sizing: border-box; + -moz-box-sizing: border-box; + width: 100%; + text-overflow: ellipsis; + overflow: hidden; + white-space: nowrap; + display: block; + padding-left: 2em; background-size: 16px 16px; background-repeat: no-repeat; - background-position: right center; + background-position: .2em center; + line-height: 2.5em; } - - #feeds li.feed:hover { - background-color: #ddd; - } - - #feeds li.feed .feeds_delete, - #feeds li.feed .feeds_edit { - display: none; - border: none; - } - - #feeds li.feed:hover .unreaditemcounter { - display: none; - } - #feeds li.feed:hover .feeds_delete, - #feeds li.feed:hover .feeds_edit, - #feeds .collapsable:hover .feeds_delete, - #feeds .collapsable:hover .feeds_edit { - display: inline-block; + #feeds li:hover > a.title { + width: 75%; } - #feeds .feeds_delete { - position: absolute; - right: 0.2em; - background: url('%webroot%/core/img/actions/delete.svg') no-repeat center; - display: none; - padding: 0; - margin: -8px 0 0 0; - top: 50%; - } - - #feeds .feeds_edit { - position: absolute; - right: 1.6em; - background: url('%webroot%/core/img/actions/rename.svg') no-repeat center; - display: none; - padding: 0; - margin: -8px 0 0 0; - top: 50%; - } - - #feeds .unreaditemcounter { - position: relative; - top: .3em; - right: .3em; - background: #5E5E5E; - border-radius: 5px; - padding: 2px 5px; - color: white; - text-align: center; - font-weight: normal; - margin: 0; - display: none; + #feeds .starred a.title { + background-image: url('%appswebroot%/news/img/starred.svg'); } - - #feeds .unreaditemcounter.all_read { - display: none !important; - } - #feeds li.collapsable_container { - background-color: #dfdfdf; - font-weight: bold; - padding: 0; - border: 0; - border-bottom: 1px solid #bbb; - position: relative; - z-index: 1; + #feeds .subscriptions a.title { + background-image: url('%appswebroot%/news/img/rss.svg'); } - #feeds li.collapsable_container.open { - background-image: linear-gradient(bottom, rgb(208,208,208) 0%, rgb(222,222,222) 100%); - background-image: -o-linear-gradient(bottom, rgb(208,208,208) 0%, rgb(222,222,222) 100%); - background-image: -moz-linear-gradient(bottom, rgb(208,208,208) 0%, rgb(222,222,222) 100%); - background-image: -webkit-linear-gradient(bottom, rgb(208,208,208) 0%, rgb(222,222,222) 100%); - background-image: -ms-linear-gradient(bottom, rgb(208,208,208) 0%, rgb(222,222,222) 100%); - font-weight: bold; - padding: 0; - border: 0; - border-bottom: 1px solid #bbb; - border-top: 1px solid #bbb; - -webkit-box-shadow: inset 0 0 5px -1px #bbb; - box-shadow: inset 0 0 5px -1px #bbb; - } + #feeds .feed { + border-bottom: 1px solid #ccc; + background-color: #f1f1f1; + } - #feeds li.collapsable_container:hover { - background-color: #d0d0d0; - -moz-transition: background-color 200ms ease 0s; - transition: background-color 200ms ease 0s; - } - + #feeds .feed:hover { + background-color: #ddd; + } + #feeds .folder { + padding: 0 .5em; + } - #feeds li.collapsable_container.open > ul { - margin: 0 8px 8px 8px; - position: relative; - z-index: 1; + #feeds .folder:hover, #feeds .starred:hover, #feeds .subscriptions:hover { + background-color: #d0d0d0; } - #feeds li.collapsable_container > ul > li { - border: 1px solid #ccc; - border-bottom: 0; - } - - #feeds li.collapsable_container > ul > li:last-child { - border: 1px solid #ccc; - } - - #feeds div.collapsable { - position: relative; - z-index: 1; - border-radius: 5px; + #feeds .folder a.title { + background-image: url('%webroot%/core/img/places/folder.svg'); } - - #feeds .collapsable_trigger { - border: none ; - margin: 0 0 0 .8em; - padding: 0; - border-radius: 0; - box-shadow: none; - vertical-align: middle !important; - background: url('%webroot%/core/img/places/folder.svg') no-repeat; - outline: none; - opacity: 1; + #feeds .folder.collapsable:hover a { + background-image: none; } - #feeds .collapsable_container:hover .collapsable_trigger.triggerable { - background-image: url('%webroot%/core/img/actions/triangle-s.svg'); - -moz-transform: none; - transform: none; - } + #feeds .folder.collapsable.open { + background-image: linear-gradient(bottom, rgb(208,208,208) 0%, rgb(222,222,222) 100%), + background-image: url('%webroot%/core/img/places/folder.svg'); + background-image: -o-linear-gradient(bottom, rgb(208,208,208) 0%, rgb(222,222,222) 100%), + background-image: url('%webroot%/core/img/places/folder.svg'); + background-image: -moz-linear-gradient(bottom, rgb(208,208,208) 0%, rgb(222,222,222) 100%), + background-image: url('%webroot%/core/img/places/folder.svg'); + background-image: -webkit-linear-gradient(bottom, rgb(208,208,208) 0%, rgb(222,222,222) 100%), + background-image: url('%webroot%/core/img/places/folder.svg'); + background-image: -ms-linear-gradient(bottom, rgb(208,208,208) 0%, rgb(222,222,222) 100%), + background-image: url('%webroot%/core/img/places/folder.svg'); + border-bottom: 1px solid #bbb; + border-top: 1px solid #bbb; + -webkit-box-shadow: inset 0 0 5px -1px #bbb; + box-shadow: inset 0 0 5px -1px #bbb; + padding-bottom: .5em; + } - #feeds .collapsable_container:hover .collapsable_trigger.triggered { - background-image: url('%webroot%/core/img/actions/triangle-s.svg'); - -moz-transform: rotate(-90deg); - transform: rotate(-90deg); + #feeds .folder.collapsable.open ul { + border: 1px solid #ccc; } - - #feeds .collapsable_title { - padding: .5em 0 .5em .5em; - line-height: 1.5em; - float: none; - display: inline-block; - position: relative; + + #feeds .folder.open ul li:last-child { + border-bottom: 0; } /* feed settings */ #feed_settings { padding: 0; - bottom: 0px; + bottom: 0; overflow:visible; height:2.8em; width: 20em; margin:0; + z-index: 2; background:#eee; - border-top:1px - solid #ccc; + border-top: 1px solid #ccc; + border-right: 1px solid #ccc; + box-sizing: border-box; + -moz-box-sizing: border-box; position:fixed; } @@ -410,6 +346,7 @@ div.add_parentfolder { background:-o-linear-gradient(#DCDCDC, #EEEEEE); background:linear-gradient(#DCDCDC, #EEEEEE); position:fixed; + z-index: 6; margin-left: 0; bottom: 2.8em; border-left:1px solid #ccc; diff --git a/index.php b/index.php index 3a42ff5ac..fccc2b1c8 100644 --- a/index.php +++ b/index.php @@ -17,7 +17,9 @@ OCP\User::checkLoggedIn(); OCP\App::checkAppEnabled('news'); OCP\App::setActiveNavigationEntry('news'); +OCP\Util::addScript('news','main'); OCP\Util::addScript('news','news'); +OCP\Util::addScript('news','menu'); OCP\Util::addScript('news','jquery.timeago'); OCP\Util::addScript('news','jquery.onscreen'); diff --git a/js/main.js b/js/main.js new file mode 100644 index 000000000..b6d21a5b2 --- /dev/null +++ b/js/main.js @@ -0,0 +1,96 @@ +/** +* ownCloud - News app +* +* @author Bernhard Posselt +* Copyright (c) 2012 - Bernhard Posselt +* +* This file is licensed under the Affero General Public License version 3 or later. +* See the COPYING-README file +* +*/ + + +var News = News || {}; + +$(document).ready(function(){ + + // basic setup + News.Feed.updateAll(); + var updateInterval = 200000; //how often the feeds should update (in msec) + setInterval('News.Feed.updateAll()', updateInterval); + + // bind listeners on the menu + var menu = new News.Menu(false); + menu.bindOn('#feeds ul'); + + + /* first run script begins */ + $('#browsebtn_firstrun, #cloudbtn_firstrun, #importbtn_firstrun').hide(); + + /* first run script ends */ + + $('#addfeed').click(function() { + News.UI.overview('#addfeed_dialog','feeddialog.php'); + }); + + $('#addfeedbtn').click(function() { + $(this).hide(); + $('#addfeed_dialog_firstrun').show(); + }); + + $('#addfolder').click(function() { + News.UI.overview('#addfolder_dialog','folderdialog.php'); + }); + + $('#addfeedfolder').click(function(event) { + News.DropDownMenu.fade($(this).children('ul')); + event.stopPropagation(); + }); + + $('#settingsbtn').on('click keydown', function() { + try { + OC.appSettings({appid:'news', loadJS:true, cache:false}); + } catch(e) { + alert(e); + } + }); + + $('#view').click(function(){ + var term; + if($(this).hasClass('show_all')){ + term = 'unread'; + $(this).addClass('show_unread').removeClass('show_all'); + } else { + term = 'all'; + $(this).addClass('show_all').removeClass('show_unread'); + } + News.Feed.filter(term); + }); + + // 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; + var scrollArea = this; + $(this).children('ul').children('.feed_item:not(.read)').each(function(){ + var item = this; + var itemOffset = $(this).position().top; + if(itemOffset <= 0 || scrolled >= scrollHeight){ + // wait and check if the item is still under the top edge + setTimeout(function(){ markItemAsRead(scrollArea, item);}, 1000); + } + }) + + }); + + $('#feed_items').scrollTop(0); + + $(document).keydown(function(e) { + if ((e.keyCode || e.which) == 74) { // 'j' key shortcut + + } + }); + +}); diff --git a/js/menu.js b/js/menu.js index 32d528156..19a869e35 100644 --- a/js/menu.js +++ b/js/menu.js @@ -18,79 +18,11 @@ * HOWTO * -We create a new instance of the menu. The first argument is its class. - - var menu = new News.Menu('feedlist'); - - -To fill it with items we use JSON. Hint: If no icons are given, default icons -are being used. A typical JSON array would look like this: - - var menuStructure = [ - { - id: 1, - title: 'New Articles', - type: News.MenuNodeType.New, - children: [], - unreadCount: 4, - }, - { - id: 1, - title: 'Starred', - type: News.MenuNodeType.Starred, - children: [], - unreadCount: 1, - }, - { - id: 1, - title: 'hi', - type: News.MenuNodeType.Folder, - unreadCount: 7, - children: [ - { - id: 2, - title: 'hi too', - type: News.MenuNodeType.Feed, - unreadCount: 4, - children: [], - icon: '/test/test.png' - }, - { - id: 2, - title: 'hi 3', - type: News.MenuNodeType.Feed, - children: [], - unreadCount: 3, - }, - ] - }, - { - id: 4, - title: 'hi 4', - type: News.MenuNodeType.Feed, - children: [], - unreadCount: 1, - }, - { - id: 114, - title: 'hi 3', - type: News.MenuNodeType.Folder, - children: [], - unreadCount: 1, - }, - ]; - - menu.populateFromJSON(menuStructure, menu); - - -Now that the menu is populated, we can render, append it into the place we'd -like to and select the current selected item - - $('#leftcontent').append(menu.render()); - var selectedType = News.MenuNodeType.Feed; - var selectedId = 3; - menu.setSelected(selectedType, selectedId); +We create a new instance of the menu. Then we need to bind it on an ul which contains +all the items: + var menu = new News.Menu(); + menu.bindOn('#feeds ul'); Updating nodes (you dont have to set all values in data): @@ -164,16 +96,15 @@ var t = t || function(app, string){ return string; }; // mock translation for lo 'Feed': 0, 'Folder': 1, 'Starred': 2, - 'New': 3 + 'Subscriptions': 3 } - // TODO: set paths for icons - MenuNodeTypeDefaultIcon = { - 'Feed': '', - 'Folder': '', - 'Starred': '', - 'New': '' - } + // map css classes to MenuNodeTypes + MenuNodeTypeClass = {}; + MenuNodeTypeClass[MenuNodeType.Feed] = 'feed'; + MenuNodeTypeClass[MenuNodeType.Folder] = 'folder'; + MenuNodeTypeClass[MenuNodeType.Starred] = 'starred'; + MenuNodeTypeClass[MenuNodeType.Subscriptions] = 'subscriptions'; News.MenuNodeType = MenuNodeType; @@ -183,255 +114,248 @@ var t = t || function(app, string){ return string; }; // mock translation for lo *#########################################################################/ /** * This is the basic menu used to construct and maintain the menu - * @param cls the css class of the element + * @param showAll if all items should be shown by default */ - Menu = function(cls){ - this._class = cls; - this._children = []; - this._parent = false; - this._id = 0; - this._$htmlElement = $('