summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--appinfo/version2
-rw-r--r--index.php8
-rw-r--r--js/menu.js270
3 files changed, 277 insertions, 3 deletions
diff --git a/appinfo/version b/appinfo/version
index 986084f36..be4cea5e2 100644
--- a/appinfo/version
+++ b/appinfo/version
@@ -1 +1 @@
-7.1 \ No newline at end of file
+7.2 \ No newline at end of file
diff --git a/index.php b/index.php
index c1ead8434..af7cc9a3f 100644
--- a/index.php
+++ b/index.php
@@ -35,11 +35,15 @@ $folderforest = $foldermapper->childrenOf(0); //retrieve all the folders
if ($allfeeds) {
$feedid = isset( $_GET['feedid'] ) ? $_GET['feedid'] : null;
if ($feedid == null) {
+ $feedmapper = new OCA\News\FeedMapper(OCP\USER::getUser($userid));
if(OCP\Config::getUserValue(OCP\USER::getUser(), 'news', 'lastViewedFeed') == null){
- $feedmapper = new OCA\News\FeedMapper(OCP\USER::getUser($userid));
- $feedid = $feedmapper->mostRecent();
+ $feedid = $feedmapper->mostRecent();
} else {
$feedid = OCP\Config::getUserValue(OCP\USER::getUser(), 'news', 'lastViewedFeed');
+ // check if feed exists in table
+ if($feedmapper->findById($feedid) === null){
+ $feedid = $feedmapper->mostRecent();
+ }
}
}
}
diff --git a/js/menu.js b/js/menu.js
new file mode 100644
index 000000000..dd57f4a22
--- /dev/null
+++ b/js/menu.js
@@ -0,0 +1,270 @@
+/**
+* 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
+*
+*/
+
+/**
+ * This file includes objects for creating and accessing the feed menu
+ */
+
+var News = News || {};
+
+(function(){
+
+ /**
+ * Enumeration for menu items
+ */
+ MenuNodeType = {
+ 'Feed': 0,
+ 'Folder': 1,
+ 'Filter': 2 // used for starred items or new items
+ }
+
+ News.MenuNodeType = MenuNodeType;
+
+
+ /**
+ * This is the basic menu used to construct and maintain the menu
+ * @param cls the css class of the element
+ * @param id the id of the element
+ */
+ Menu = function(cls, id){
+ this._class = cls;
+ this._children = [];
+ this._parent = false;
+ this._id = id;
+ this._$htmlElement = $('<ul>');
+ }
+
+ Menu.prototype.addChild = function(node){
+ node.setParent(this);
+ this._children.push(node);
+ }
+
+ Menu.prototype.setParent = function(node){
+ this._parent = node;
+ }
+
+ /**
+ * Recursively traverse the menu and returns the
+ * Node element matching the type and id
+ * @return the node element
+ */
+ Menu.prototype.findNode = function(id, type){
+ for(var i=0; i<this._children.length; i++){
+ var child = this._children[i];
+ if(child._type === type && child._id === id){
+ return child;
+ } else {
+ return child.findNode(type, id);
+ }
+ }
+ }
+
+ /**
+ * Recursively remove all occurences of the node from the dom and
+ * from the datastructure
+ */
+ Menu.prototype.removeNode = function(id, type){
+ var nodeIndex;
+ for(var i=0; i<this._children.length; i++){
+ var child = this._children[i];
+ if(child._type === type && child._id === id){
+ var nodeIndex = i;
+ // if we have children, we need to remove their
+ // html from the dom first then we need to
+ this._$htmlElement.remove(child);
+ this._children.splice(nodeIndex, 1);
+ } else {
+ child.removeNode(type, id);
+ }
+ }
+ }
+
+ /**
+ * Creates the menu from a json structure
+ * @param json the json looks like this
+ [
+ {
+ id: 1,,
+ title: 'hi',
+ type: MenuNodeType.Folder,
+ icon: 'url/to/jpg.png',
+ children: [
+ {
+ id: 1,
+ title: 'hi too',
+ type: MenuNodeType.Feed,
+ children: []
+ },
+ {
+ ...
+ }
+ ]
+ },
+ {
+ ...
+ }
+ ]
+ * @param attachToNode used for recursion. to set the current
+ * element to the node, pass the current structure
+ */
+ Menu.prototype.populateFromJSON = function(json, attachToNode){
+ for(var i=0; i<json.length; i++){
+ var nodeInfo = json[i];
+ var node = new MenuNode(nodeInfo.title, nodeInfo.id,
+ nodeInfo.type, nodeInfo.icon, nodeInfo.unreadCount);
+ attachToNode.addChild(node);
+ this.populateFromJSON(nodeInfo.children, node);
+ }
+ }
+
+ /**
+ * Sets the unreadcount for all items from json markup
+ * format of json is:
+ [
+ {
+ id: '1',
+ type: 1,
+ unreadCount: 39
+ },
+ {
+ ...
+ }
+ ]
+ */
+ Menu.prototype.setUnreadCountFromJSON = function(json){
+ for(var i=0; i<json.length; i++){
+ var element = json[i];
+ var node = this.findNode(element.id, element.type);
+ node.setUnreadCount(element.unreadCount);
+ }
+ }
+
+
+ Menu.prototype.render = function(){
+ var $html = this._$htmlElement.addClass(this._class).data('id', this._id);
+ for(var i=0; i<this._children.length; i++){
+ var child = this._children[i];
+ var childHTML = child.render();
+ $html.append(childHTML);
+ }
+ return $html;
+ }
+
+ News.Menu = Menu;
+
+
+ /**
+ * Items which are in the menu
+ * @param title the caption of the menu item
+ * @param type the type of the node, a MenuNodeType
+ * @param id the id of the node. id and type must be unique!
+ * @param icon is the little image that appears left of the caption
+ * @param unreadCount the current count of unread items
+ */
+ MenuNode = function(title, id, type, icon, unreadCount){
+ this._type = type;
+ this._id = id;
+ this._title = title;
+ this._$htmlElement = $('<li>');
+ this._children = [];
+ this.setUnreadCount(unreadCount);
+ this.setIcon(icon);
+ }
+
+ MenuNode.prototype = Object.create(Menu.prototype);
+
+ /**
+ * Sets the unread count and handles the appropriate css
+ * classes
+ */
+ MenuNode.prototype.setUnreadCount = function(unreadCount){
+ unreadCount = parseInt(unreadCount);
+
+ if(unreadCount === 0){
+ this._$htmlElement.addClass('all_read');
+ }
+
+ if(this._unreadCount !== undefined && this._unreadCount === 0
+ && unreadCount > 0){
+ this._$htmlElement.removeClass('all_read');
+ }
+
+ this._unreadCount = unreadCount;
+ }
+
+ MenuNode.prototype.increaseUnreadCount = function(by){
+ this._unreadCount += parseInt(by);
+ }
+
+ MenuNode.prototype.decreaseUnreadCount = function(by){
+ this._unreadCount -= parseInt(by);
+ }
+
+ MenuNode.prototype.changeTitle = function(title){
+ this._title = title;
+ this._$htmlElement.children('.title').html(this._title);
+ }
+
+ MenuNode.prototype.setIcon = function(icon){
+ if(icon !== undefined){
+ this._icon = icon;
+ this._$htmlElement.css('background-image', this._icon);
+ }
+ }
+
+ /**
+ * Toggles the selection class
+ */
+ MenuNode.prototype.toggleSelected = function(){
+ this._$htmlElement.toggle('selected');
+ }
+
+ MenuNode.prototype.render = function(){
+ var $elem = this._$htmlElement;
+
+ // set the type class
+ switch(this._type){
+ case MenuNodeType.Feed:
+ $elem.addClass('feed');
+ break;
+
+ case MenuNodeType.Folder:
+ $elem.addClass('folder');
+ break;
+
+ case MenuNodeType.Filter:
+ $elem.addClass('filter');
+ break;
+
+ default:
+ break;
+ }
+
+ var $title = $('<span>').addClass('title').html(this._title);
+ $elem.append($title);
+
+ var $subNode = $('<ul>');
+
+ for(var i=0; i<this._children.length; i++){
+ var node = this._children[i];
+ $subNode.append(node.render());
+ }
+
+ if(this._children.length > 0){
+ $elem.append($subNode);
+ }
+
+ return $elem;
+ }
+
+ News.MenuNode = MenuNode;
+
+})(); \ No newline at end of file