diff --git a/couchpotato/core/notifications/core/main.py b/couchpotato/core/notifications/core/main.py index df53347d..c3a16214 100644 --- a/couchpotato/core/notifications/core/main.py +++ b/couchpotato/core/notifications/core/main.py @@ -33,6 +33,19 @@ class CoreNotifier(Notification): 'id': {'desc': 'Notification id you want to mark as read.', 'type': 'int (comma separated)'}, }, }) + + addApiView('notification.list', self.listView, docs = { + 'desc': 'Get list of notifications', + 'params': { + 'limit_offset': {'desc': 'Limit and offset the notification list. Examples: "50" or "50,30"'}, + }, + 'return': {'type': 'object', 'example': """{ + 'success': True, + 'empty': bool, any notification returned or not, + 'notifications': array, notifications found, +}"""} + }) + addApiView('notification.listener', self.listener) self.registerEvents() @@ -57,6 +70,32 @@ class CoreNotifier(Notification): 'success': True }) + def listView(self): + + db = get_session() + limit_offset = getParam('limit_offset', None) + + q = db.query(Notif) + + if limit_offset: + splt = limit_offset.split(',') + limit = splt[0] + offset = 0 if len(splt) is 1 else splt[1] + q = q.limit(limit).offset(offset) + + results = q.all() + notifications = [] + for n in results: + ndict = n.to_dict() + ndict['type'] = 'notification' + notifications.append(ndict) + + return jsonified({ + 'success': True, + 'empty': len(notifications) == 0, + 'notifications': notifications + }) + def notify(self, message = '', data = {}): db = get_session() @@ -93,7 +132,10 @@ class CoreNotifier(Notification): # Get unread if getParam('init'): db = get_session() - notifications = db.query(Notif).filter_by(read = False).all() + + notifications = db.query(Notif) \ + .filter(or_(Notif.read == False, Notif.added > (time.time() - 259200))) \ + .all() for n in notifications: ndict = n.to_dict() ndict['type'] = 'notification' diff --git a/couchpotato/core/notifications/core/static/notification.js b/couchpotato/core/notifications/core/static/notification.js index 617ef2ac..371b95ed 100644 --- a/couchpotato/core/notifications/core/static/notification.js +++ b/couchpotato/core/notifications/core/static/notification.js @@ -26,10 +26,10 @@ var NotificationBase = new Class({ $(App.block.notification).inject(App.getBlock('search'), 'after'); self.badge = new Element('div.badge').inject(App.block.notification, 'top').hide(); - App.getBlock('notification').addLink(new Element('a.more', { + /* App.getBlock('notification').addLink(new Element('a.more', { 'href': App.createUrl('notifications'), - 'text': 'See more notifications' - })); + 'text': 'Show older notifications' + })); */ }) }, @@ -41,7 +41,7 @@ var NotificationBase = new Class({ added.setTime(result.added*1000) result.el = App.getBlock('notification').addLink( - new Element('span').adopt( + new Element('span.'+(result.read ? 'read' : '' )).adopt( new Element('span.message', {'text': result.message}), new Element('span.added', {'text': added.timeDiffInWords(), 'title': added}) ) @@ -51,11 +51,6 @@ var NotificationBase = new Class({ if(!result.read) self.setBadge(self.notifications.filter(function(n){ return !n.read}).length) - if(self.notifications.length >= 5){ - var n = self.notifications[self.notifications.length-5]; - n.el.destroy(); - } - }, setBadge: function(value){ @@ -76,14 +71,15 @@ var NotificationBase = new Class({ ids.include(n.id) }) - Api.request('notification.markread', { - 'data': { - 'ids': ids.join(',') - }, - 'onSuccess': function(){ - self.setBadge('') - } - }) + if(ids.length > 0) + Api.request('notification.markread', { + 'data': { + 'ids': ids.join(',') + }, + 'onSuccess': function(){ + self.setBadge('') + } + }) }, diff --git a/couchpotato/core/plugins/movie/main.py b/couchpotato/core/plugins/movie/main.py index 32cee0c5..433ecaa9 100644 --- a/couchpotato/core/plugins/movie/main.py +++ b/couchpotato/core/plugins/movie/main.py @@ -41,7 +41,7 @@ class MoviePlugin(Plugin): 'desc': 'List movies in wanted list', 'params': { 'status': {'type': 'array or csv', 'desc': 'Filter movie by status. Example:"active,done"'}, - 'limit_offset': {'desc': 'Limit the movie list. Examples: "50", "50,30"'}, + 'limit_offset': {'desc': 'Limit and offset the movie list. Examples: "50" or "50,30"'}, 'starts_with': {'desc': 'Starts with these characters. Example: "a" returns all movies starting with the letter "a"'}, 'search': {'desc': 'Search movie title'}, }, diff --git a/couchpotato/core/plugins/movie/static/movie.css b/couchpotato/core/plugins/movie/static/movie.css index 36ff17c3..b66d0467 100644 --- a/couchpotato/core/plugins/movie/static/movie.css +++ b/couchpotato/core/plugins/movie/static/movie.css @@ -89,6 +89,7 @@ font-size: 16px; font-weight: normal; text-overflow: ellipsis; + width: 64%; } .movies .info .year { @@ -125,12 +126,22 @@ .movies .list_view .info .description, .movies .mass_edit_view .info .description { display: none; } - + + .movies .data .quality { + display: block; + min-height: 20px; + vertical-align: mid; + } + .movies .data .quality span { padding: 2px 3px; font-weight: bold; opacity: 0.5; font-size: 10px; + height: 16px; + line-height: 12px; + vertical-align: middle; + display: inline-block; text-transform: uppercase; text-shadow: none; font-weight: normal; @@ -141,7 +152,7 @@ .movies .list_view .data .quality, .movies .mass_edit_view .data .quality { text-align: right; float: right; - width: 35%; + width: 30%; } .movies .data .quality .available, .movies .data .quality .snatched { @@ -152,6 +163,10 @@ .movies .data .quality .available { background-color: #578bc3; } .movies .data .quality .snatched { background-color: #369545; } + .movies .data .quality .done { + background-color: #369545; + opacity: 1; + } .movies .data .quality .finish { background-image: url('../images/sprite.png'); background-repeat: no-repeat; @@ -183,7 +198,7 @@ } .movies .list_view .data:hover .actions, .movies .mass_edit_view .data:hover .actions { - margin: -35px -7px 0 0; + margin: -34px 2px 0 0; background: #4e5969; } @@ -272,7 +287,7 @@ text-align: left; padding: 0 10px; } - .movies .options .table.files .name { width: 608px; } + .movies .options .table.files .name { width: 605px; } .movies .options .table .type { width: 130px; } .movies .options .table .is_available { width: 90px; } diff --git a/couchpotato/core/plugins/movie/static/movie.js b/couchpotato/core/plugins/movie/static/movie.js index 53cd9e31..ee26ab95 100644 --- a/couchpotato/core/plugins/movie/static/movie.js +++ b/couchpotato/core/plugins/movie/static/movie.js @@ -49,7 +49,9 @@ var Movie = new Class({ self.quality = new Element('div.quality', { 'events': { 'click': function(e){ - self.el.getElement('.actions .releases').fireEvent('click', [e]) + var releases = self.el.getElement('.actions .releases'); + if(releases) + releases.fireEvent('click', [e]) } } }) @@ -101,7 +103,7 @@ var Movie = new Class({ var q = Quality.getQuality(quality_id); return new Element('span', { 'text': q.label, - 'class': 'q_'+q.identifier + 'q_id' + q.quality_id + 'class': 'q_'+q.identifier + ' q_id' + q.id }).inject(self.quality); }, diff --git a/couchpotato/static/scripts/block/menu.js b/couchpotato/static/scripts/block/menu.js index f8ca6f11..4dc143d4 100644 --- a/couchpotato/static/scripts/block/menu.js +++ b/couchpotato/static/scripts/block/menu.js @@ -12,7 +12,9 @@ Block.Menu = new Class({ self.el = new Element('div', { 'class': 'more_menu '+self.options['class'] }).adopt( - self.more_option_ul = new Element('ul'), + self.wrapper = new Element('div.wrapper').adopt( + self.more_option_ul = new Element('ul') + ), new Element('a.button.onlay', { 'events': { 'click': function(){ diff --git a/couchpotato/static/style/main.css b/couchpotato/static/style/main.css index fd66f0eb..9975da70 100644 --- a/couchpotato/static/style/main.css +++ b/couchpotato/static/style/main.css @@ -235,11 +235,11 @@ body > .spinner, .mask{ .header .more_menu { margin-left: 12px; } - .header .more_menu ul { + .header .more_menu .wrapper { width: 150px; margin-left: -110px; } - .header .more_menu ul:before { + .header .more_menu .wrapper:before { margin-left: -34px; } @@ -262,15 +262,21 @@ body > .spinner, .mask{ text-shadow: none; } - .header .notification_menu ul { + .header .notification_menu .wrapper { width: 300px; margin-left: -260px; text-align: left; } - .header .notification_menu ul:before { + + .header .notification_menu .wrapper:before { left: 296px; } + .header .notification_menu ul { + max-height: 300px; + overflow: auto; + } + .header .notification_menu > a { background-position: center -209px; } @@ -280,6 +286,8 @@ body > .spinner, .mask{ display: block; border-bottom: 1px solid rgba(0,0,0,0.2); } + .header .notification_menu li > span { color: #777; } + .header .notification_menu li:last-child > span { border: 0; } .header .notification_menu li .added { display: block; font-size: 10px; @@ -509,7 +517,7 @@ body > .spinner, .mask{ background-color: #406db8; } - .more_menu ul { + .more_menu .wrapper { display: none; border: 1px solid #333; background: rgba(255,255,255,0.98); @@ -520,7 +528,6 @@ body > .spinner, .mask{ margin: 32px 0 0 -145px; width: 185px; box-shadow: 0 10px 10px -5px rgba(0,0,0,0.4); - list-style: none; text-align: center; color: #000; text-shadow: none; @@ -538,7 +545,7 @@ body > .spinner, .mask{ ); } - .more_menu ul:before { + .more_menu .wrapper:before { content: ' '; height: 0; position: relative; @@ -549,15 +556,22 @@ body > .spinner, .mask{ top: -16px; left: 146px; } - .more_menu.show ul { + .more_menu.show .wrapper { display: block; } - .more_menu ul li { + + .more_menu ul { + padding: 0; + margin: -12px 0 0 0; + list-style: none; + } + + .more_menu .wrapper li { width: 100%; height: auto; } - .more_menu ul li a { + .more_menu .wrapper li a { display: block; border-bottom: 1px solid rgba(255,255,255,0.2); box-shadow: none; @@ -568,14 +582,10 @@ body > .spinner, .mask{ padding: 3px 0; color: #000; } - - .more_menu ul li:first-child { - margin-top: -12px; - } - .more_menu ul li:last-child a { + .more_menu .wrapper li:last-child a { border: none; } - .more_menu ul li a:hover { + .more_menu .wrapper li a:hover { background: rgba(0,0,0,0.05); } \ No newline at end of file