From 1e1b64539144006c59c7b705700fc7f34c7a26b1 Mon Sep 17 00:00:00 2001 From: RaNaN Date: Wed, 20 Feb 2013 12:00:22 +0100 Subject: more animation for dashboard --- module/api/ConfigApi.py | 2 +- module/api/FileApi.py | 6 ++ module/database/DatabaseBackend.py | 1 + module/database/FileDatabase.py | 46 ++++---- module/datatypes/PyPackage.py | 10 +- module/remote/pyload.thrift | 10 +- module/remote/ttypes.py | 29 +++--- module/remote/ttypes_debug.py | 11 +- module/web/static/css/default/dashboard.less | 5 +- module/web/static/css/default/style.less | 11 +- module/web/static/js/default.js | 10 +- module/web/static/js/models/Package.js | 1 + module/web/static/js/utils/animations.js | 36 ++----- module/web/static/js/views/abstract/itemView.js | 3 +- module/web/static/js/views/actionbarView.js | 28 +++++ module/web/static/js/views/dashboardView.js | 133 ++++++++++++++++++++++++ module/web/static/js/views/packageTreeView.js | 115 -------------------- module/web/static/js/views/packageView.js | 21 +--- module/web/static/js/views/selectionView.js | 59 ++++++++++- module/web/templates/default/dashboard.html | 12 ++- tests/other/test_filedatabase.py | 1 + 21 files changed, 326 insertions(+), 224 deletions(-) create mode 100644 module/web/static/js/views/actionbarView.js create mode 100644 module/web/static/js/views/dashboardView.js delete mode 100644 module/web/static/js/views/packageTreeView.js diff --git a/module/api/ConfigApi.py b/module/api/ConfigApi.py index ffcdbabec..451e4f832 100644 --- a/module/api/ConfigApi.py +++ b/module/api/ConfigApi.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -from module.Api import Api, UserContext, RequirePerm, Permission, ConfigHolder, ConfigItem, PluginInfo +from module.Api import Api, UserContext, RequirePerm, Permission, ConfigHolder, ConfigItem, ConfigInfo from module.utils import to_string from ApiComponent import ApiComponent diff --git a/module/api/FileApi.py b/module/api/FileApi.py index f470cfa3e..fa9d728cb 100644 --- a/module/api/FileApi.py +++ b/module/api/FileApi.py @@ -76,6 +76,12 @@ class FileApi(ApiComponent): def findFiles(self, pattern): pass + @RequirePerm(Permission.All) + def getAutocompletion(self, pattern): + # TODO + + return ["static", "autocompletion", "demo"] + @RequirePerm(Permission.All) def findPackages(self, tags): pass diff --git a/module/database/DatabaseBackend.py b/module/database/DatabaseBackend.py index 6e67c799a..e77fc0966 100644 --- a/module/database/DatabaseBackend.py +++ b/module/database/DatabaseBackend.py @@ -244,6 +244,7 @@ class DatabaseBackend(Thread): '"added" INTEGER DEFAULT 0 NOT NULL,' # set by trigger '"status" INTEGER DEFAULT 0 NOT NULL,' '"tags" TEXT DEFAULT "" NOT NULL,' + '"shared" INTEGER DEFAULT 0 NOT NULL,' '"packageorder" INTEGER DEFAULT -1 NOT NULL,' #incremented by trigger '"root" INTEGER DEFAULT -1 NOT NULL, ' '"owner" INTEGER NOT NULL, ' diff --git a/module/database/FileDatabase.py b/module/database/FileDatabase.py index b303b9b0f..9d11ffe46 100644 --- a/module/database/FileDatabase.py +++ b/module/database/FileDatabase.py @@ -22,6 +22,7 @@ from module.database import DatabaseMethods, queue, async, inner zero_stats = PackageStats(0, 0, 0, 0) + class FileMethods(DatabaseMethods): @queue def filecount(self, user=None): @@ -55,21 +56,22 @@ class FileMethods(DatabaseMethods): def addLink(self, url, name, plugin, package, owner): # mark file status initially as missing, dlstatus - queued self.c.execute('INSERT INTO files(url, name, plugin, status, dlstatus, package, owner) VALUES(?,?,?,1,3,?,?)', - (url, name, plugin, package, owner)) + (url, name, plugin, package, owner)) return self.c.lastrowid @async def addLinks(self, links, package, owner): """ links is a list of tuples (url, plugin)""" links = [(x[0], x[0], x[1], package, owner) for x in links] - self.c.executemany('INSERT INTO files(url, name, plugin, status, dlstatus, package, owner) VALUES(?,?,?,1,3,?,?)', + self.c.executemany( + 'INSERT INTO files(url, name, plugin, status, dlstatus, package, owner) VALUES(?,?,?,1,3,?,?)', links) @queue def addFile(self, name, size, media, package, owner): # file status - ok, dl status NA self.c.execute('INSERT INTO files(name, size, media, package, owner) VALUES(?,?,?,?,?)', - (name, size, media, package, owner)) + (name, size, media, package, owner)) return self.c.lastrowid @queue @@ -93,11 +95,11 @@ class FileMethods(DatabaseMethods): if owner is None: self.c.execute('DELETE FROM files WHERE fid=?', (fid,)) self.c.execute('UPDATE files SET fileorder=fileorder-1 WHERE fileorder > ? AND package=?', - (order, package)) + (order, package)) else: self.c.execute('DELETE FROM files WHERE fid=? AND owner=?', (fid, owner)) self.c.execute('UPDATE files SET fileorder=fileorder-1 WHERE fileorder > ? AND package=? AND owner=?', - (order, package, owner)) + (order, package, owner)) @async def saveCollector(self, owner, data): @@ -132,7 +134,7 @@ class FileMethods(DatabaseMethods): arg = [] if state is not None and state != DS.All: - qry += 'dlstatus IN (%s) AND ' % state_string(state) + qry += 'dlstatus IN (%s) AND ' % state_string(state) if owner is not None: qry += 'owner=? AND ' arg.append(owner) @@ -169,8 +171,9 @@ class FileMethods(DatabaseMethods): :param owner: optional user id :param tags: optional tag list """ - qry = ('SELECT pid, name, folder, root, owner, site, comment, password, added, tags, status, packageorder ' - 'FROM packages%s ORDER BY root, packageorder') + qry = ( + 'SELECT pid, name, folder, root, owner, site, comment, password, added, tags, status, shared, packageorder ' + 'FROM packages%s ORDER BY root, packageorder') if root is None: stats = self.getPackageStats(owner=owner) @@ -188,7 +191,8 @@ class FileMethods(DatabaseMethods): data = OrderedDict() for r in self.c: data[r[0]] = PackageInfo( - r[0], r[1], r[2], r[3], r[4], r[5], r[6], r[7], r[8], r[9].split(","), r[10], r[11], stats.get(r[0], zero_stats) + r[0], r[1], r[2], r[3], r[4], r[5], r[6], r[7], r[8], r[9].split(","), r[10], r[11], r[12], + stats.get(r[0], zero_stats) ) return data @@ -249,15 +253,17 @@ class FileMethods(DatabaseMethods): if stats: stats = self.getPackageStats(pid=pid) - self.c.execute('SELECT pid, name, folder, root, owner, site, comment, password, added, tags, status, packageorder ' - 'FROM packages WHERE pid=?', (pid,)) + self.c.execute( + 'SELECT pid, name, folder, root, owner, site, comment, password, added, tags, status, shared, packageorder ' + 'FROM packages WHERE pid=?', (pid,)) r = self.c.fetchone() if not r: return None else: return PackageInfo( - r[0], r[1], r[2], r[3], r[4], r[5], r[6], r[7], r[8], r[9].split(","), r[10], r[11], stats.get(r[0], zero_stats) if stats else None + r[0], r[1], r[2], r[3], r[4], r[5], r[6], r[7], r[8], r[9].split(","), r[10], r[11], r[12], + stats.get(r[0], zero_stats) if stats else None ) @async @@ -265,7 +271,7 @@ class FileMethods(DatabaseMethods): """ data is list of tuples (name, size, status,[ hash,] url)""" if data and len(data[0]) == 4: self.c.executemany('UPDATE files SET name=?, size=?, dlstatus=? WHERE url=? AND dlstatus IN (0,1,2,3,14)', - data) + data) else: self.c.executemany( 'UPDATE files SET name=?, size=?, dlstatus=?, hash=? WHERE url=? AND dlstatus IN (0,1,2,3,14)', data) @@ -274,13 +280,14 @@ class FileMethods(DatabaseMethods): def updateFile(self, f): self.c.execute('UPDATE files SET name=?, size=?, status=?,' 'media=?, url=?, hash=?, dlstatus=?, error=? WHERE fid=?', - (f.name, f.size, f.filestatus, f.media, f.url, - f.hash, f.status, f.error, f.fid)) + (f.name, f.size, f.filestatus, f.media, f.url, + f.hash, f.status, f.error, f.fid)) @async def updatePackage(self, p): - self.c.execute('UPDATE packages SET name=?, folder=?, site=?, comment=?, password=?, tags=?, status=? WHERE pid=?', - (p.name, p.folder, p.site, p.comment, p.password, ",".join(p.tags), p.status, p.pid)) + self.c.execute( + 'UPDATE packages SET name=?, folder=?, site=?, comment=?, password=?, tags=?, status=?, shared=? WHERE pid=?', + (p.name, p.folder, p.site, p.comment, p.password, ",".join(p.tags), p.status, p.shared, p.pid)) # TODO: most modifying methods needs owner argument to avoid checking beforehand @async @@ -320,7 +327,7 @@ class FileMethods(DatabaseMethods): order = (r[0] if r[0] else 0) + 1 self.c.execute('UPDATE files SET fileorder=fileorder-? WHERE fileorder > ? AND package=?', - (len(fids), order, pid)) + (len(fids), order, pid)) data = [(package, order + i, fid) for i, fid in enumerate(fids)] self.c.executemany('UPDATE files SET package=?, fileorder=? WHERE fid=?', data) @@ -332,7 +339,7 @@ class FileMethods(DatabaseMethods): max = (r[0] if r[0] else 0) + 1 self.c.execute('UPDATE packages SET packageorder=packageorder-1 WHERE packageorder > ? AND root=?', - (order, root)) + (order, root)) self.c.execute('UPDATE packages SET root=?, packageorder=? WHERE pid=?', (dpid, max, pid)) @@ -396,4 +403,5 @@ class FileMethods(DatabaseMethods): self.c.execute("DELETE FROM files") self.c.execute("DELETE FROM collector") + FileMethods.register() \ No newline at end of file diff --git a/module/datatypes/PyPackage.py b/module/datatypes/PyPackage.py index 4118af190..6ba37ee12 100644 --- a/module/datatypes/PyPackage.py +++ b/module/datatypes/PyPackage.py @@ -29,9 +29,10 @@ class PyPackage: @staticmethod def fromInfoData(m, info): return PyPackage(m, info.pid, info.name, info.folder, info.root, info.owner, - info.site, info.comment, info.password, info.added, info.tags, info.status, info.packageorder) + info.site, info.comment, info.password, info.added, info.tags, info.status, info.shared, info.packageorder) - def __init__(self, manager, pid, name, folder, root, owner, site, comment, password, added, tags, status, packageorder): + def __init__(self, manager, pid, name, folder, root, owner, site, comment, password, added, tags, status, + shared, packageorder): self.m = manager self.pid = pid @@ -45,6 +46,7 @@ class PyPackage: self.added = added self.tags = tags self.status = status + self.shared = shared self.packageorder = packageorder self.timestamp = time() @@ -61,7 +63,7 @@ class PyPackage: def toInfoData(self): return PackageInfo(self.pid, self.name, self.folder, self.root, self.ownerid, self.site, - self.comment, self.password, self.added, self.tags, self.status, self.packageorder + self.comment, self.password, self.added, self.tags, self.status, self.shared, self.packageorder ) def getChildren(self): @@ -97,7 +99,7 @@ class PyPackage: class RootPackage(PyPackage): def __init__(self, m, owner): - PyPackage.__init__(self, m, -1, "root", "", owner, -2, "", "", "", 0, [], PackageStatus.Ok, 0) + PyPackage.__init__(self, m, -1, "root", "", owner, -2, "", "", "", 0, [], PackageStatus.Ok, False, 0) def getPath(self, name=""): return join(self.m.core.config["general"]["download_folder"], name) diff --git a/module/remote/pyload.thrift b/module/remote/pyload.thrift index 077810ecb..6a77bdc1d 100644 --- a/module/remote/pyload.thrift +++ b/module/remote/pyload.thrift @@ -179,10 +179,11 @@ struct PackageInfo { 9: UTCDate added, 10: list tags, 11: PackageStatus status, - 12: i16 packageorder, - 13: PackageStats stats, - 14: list fids, - 15: list pids, + 12: bool shared, + 13: i16 packageorder, + 14: PackageStats stats, + 15: list fids, + 16: list pids, } // thrift does not allow recursive datatypes, so all data is accumulated and mapped with id @@ -449,6 +450,7 @@ service Pyload { FileInfo getFileInfo(1: FileID fid) throws (1: FileDoesNotExists e), TreeCollection findFiles(1: string pattern), + list getAutocompletion(1: string pattern), TreeCollection findPackages(1: list tags), // Modify Files/Packages diff --git a/module/remote/ttypes.py b/module/remote/ttypes.py index e8ef26dd2..1592829a3 100644 --- a/module/remote/ttypes.py +++ b/module/remote/ttypes.py @@ -138,6 +138,17 @@ class ConfigHolder(BaseObject): self.info = info self.handler = handler +class ConfigInfo(BaseObject): + __slots__ = ['name', 'label', 'description', 'addon', 'user_context', 'activated'] + + def __init__(self, name=None, label=None, description=None, addon=None, user_context=None, activated=None): + self.name = name + self.label = label + self.description = description + self.addon = addon + self.user_context = user_context + self.activated = activated + class ConfigItem(BaseObject): __slots__ = ['name', 'label', 'description', 'type', 'default_value', 'value'] @@ -244,9 +255,9 @@ class PackageDoesNotExists(ExceptionObject): self.pid = pid class PackageInfo(BaseObject): - __slots__ = ['pid', 'name', 'folder', 'root', 'owner', 'site', 'comment', 'password', 'added', 'tags', 'status', 'packageorder', 'stats', 'fids', 'pids'] + __slots__ = ['pid', 'name', 'folder', 'root', 'owner', 'site', 'comment', 'password', 'added', 'tags', 'status', 'shared', 'packageorder', 'stats', 'fids', 'pids'] - def __init__(self, pid=None, name=None, folder=None, root=None, owner=None, site=None, comment=None, password=None, added=None, tags=None, status=None, packageorder=None, stats=None, fids=None, pids=None): + def __init__(self, pid=None, name=None, folder=None, root=None, owner=None, site=None, comment=None, password=None, added=None, tags=None, status=None, shared=None, packageorder=None, stats=None, fids=None, pids=None): self.pid = pid self.name = name self.folder = folder @@ -258,6 +269,7 @@ class PackageInfo(BaseObject): self.added = added self.tags = tags self.status = status + self.shared = shared self.packageorder = packageorder self.stats = stats self.fids = fids @@ -272,17 +284,6 @@ class PackageStats(BaseObject): self.sizetotal = sizetotal self.sizedone = sizedone -class PluginInfo(BaseObject): - __slots__ = ['name', 'label', 'description', 'addon', 'user_context', 'activated'] - - def __init__(self, name=None, label=None, description=None, addon=None, user_context=None, activated=None): - self.name = name - self.label = label - self.description = description - self.addon = addon - self.user_context = user_context - self.activated = activated - class ProgressInfo(BaseObject): __slots__ = ['plugin', 'name', 'statusmsg', 'eta', 'done', 'total', 'download'] @@ -416,6 +417,8 @@ class Iface(object): pass def getAllUserData(self): pass + def getAutocompletion(self, pattern): + pass def getAvailablePlugins(self): pass def getCollector(self): diff --git a/module/remote/ttypes_debug.py b/module/remote/ttypes_debug.py index 17d602f97..84b56e55d 100644 --- a/module/remote/ttypes_debug.py +++ b/module/remote/ttypes_debug.py @@ -10,6 +10,7 @@ classes = { 'AddonInfo' : [basestring, basestring, basestring], 'AddonService' : [basestring, basestring, (list, basestring), (None, int)], 'ConfigHolder' : [basestring, basestring, basestring, basestring, (list, ConfigItem), (None, (list, AddonInfo)), (None, (list, InteractionTask))], + 'ConfigInfo' : [basestring, basestring, basestring, bool, bool, (None, bool)], 'ConfigItem' : [basestring, basestring, basestring, basestring, (None, basestring), basestring], 'DownloadInfo' : [basestring, basestring, basestring, int, basestring, basestring], 'DownloadProgress' : [int, int, int, int], @@ -21,9 +22,8 @@ classes = { 'LinkStatus' : [basestring, basestring, basestring, int, int, basestring], 'OnlineCheck' : [int, (dict, basestring, LinkStatus)], 'PackageDoesNotExists' : [int], - 'PackageInfo' : [int, basestring, basestring, int, int, basestring, basestring, basestring, int, (list, basestring), int, int, PackageStats, (list, int), (list, int)], + 'PackageInfo' : [int, basestring, basestring, int, int, basestring, basestring, basestring, int, (list, basestring), int, bool, int, PackageStats, (list, int), (list, int)], 'PackageStats' : [int, int, int, int], - 'PluginInfo' : [basestring, basestring, basestring, bool, bool, (None, bool)], 'ProgressInfo' : [basestring, basestring, basestring, int, int, int, (None, DownloadProgress)], 'ServerStatus' : [int, int, int, bool, bool, bool], 'ServiceDoesNotExists' : [basestring, basestring], @@ -65,11 +65,12 @@ methods = { 'getAddonHandler': (dict, basestring, list), 'getAllFiles': TreeCollection, 'getAllUserData': (dict, int, UserData), - 'getAvailablePlugins': (list, PluginInfo), + 'getAutocompletion': (list, basestring), + 'getAvailablePlugins': (list, ConfigInfo), 'getCollector': (list, LinkStatus), 'getConfig': (dict, basestring, ConfigHolder), 'getConfigValue': basestring, - 'getCoreConfig': (list, PluginInfo), + 'getCoreConfig': (list, ConfigInfo), 'getEvents': (list, EventInfo), 'getFileInfo': FileInfo, 'getFileTree': TreeCollection, @@ -80,7 +81,7 @@ methods = { 'getNotifications': (list, InteractionTask), 'getPackageContent': TreeCollection, 'getPackageInfo': PackageInfo, - 'getPluginConfig': (list, PluginInfo), + 'getPluginConfig': (list, ConfigInfo), 'getProgressInfo': (list, ProgressInfo), 'getServerStatus': ServerStatus, 'getServerVersion': basestring, diff --git a/module/web/static/css/default/dashboard.less b/module/web/static/css/default/dashboard.less index a582e7326..4d504fdc3 100644 --- a/module/web/static/css/default/dashboard.less +++ b/module/web/static/css/default/dashboard.less @@ -58,6 +58,8 @@ position: absolute; height: @frame-bottom; line-height: @frame-bottom; + font-size: 12px; + text-align: center; border-radius: 0; border-bottom-left-radius: 5px; border-bottom-right-radius: 5px; @@ -66,6 +68,7 @@ right: 0; margin-bottom: 0; background-image: none; + color: @light; background-color: @yellow; } @@ -176,7 +179,7 @@ width: 50%; font-weight: bold; - i { + .icon-file { cursor: move; } diff --git a/module/web/static/css/default/style.less b/module/web/static/css/default/style.less index 7db464c92..3e2a42abf 100644 --- a/module/web/static/css/default/style.less +++ b/module/web/static/css/default/style.less @@ -333,8 +333,15 @@ header .logo { left: 50%; bottom: -28px; min-width: 15%; -// color: @dark; -// background-color: @light; + + i { + cursor: pointer; + + &:hover { + color: @yellow; + } + } + } /* diff --git a/module/web/static/js/default.js b/module/web/static/js/default.js index bb9701935..afe624ff9 100644 --- a/module/web/static/js/default.js +++ b/module/web/static/js/default.js @@ -1,15 +1,15 @@ -define('default', ['require', 'jquery', 'app', 'views/headerView', 'views/packageTreeView'], - function(require, $, App, HeaderView, TreeView) { +define('default', ['require', 'jquery', 'app', 'views/headerView', 'views/dashboardView'], + function(require, $, App, HeaderView, DashboardView) { App.init = function() { App.header = new HeaderView(); App.header.render(); }; - App.initPackageTree = function() { + App.initDashboard = function() { $(function() { - App.treeView = new TreeView(); - App.treeView.init(); + App.dashboard = new DashboardView(); + App.dashboard.init(); }); }; diff --git a/module/web/static/js/models/Package.js b/module/web/static/js/models/Package.js index 7539b0673..24f04519e 100644 --- a/module/web/static/js/models/Package.js +++ b/module/web/static/js/models/Package.js @@ -17,6 +17,7 @@ define(['jquery', 'backbone', 'underscore', 'collections/FileList', 'require'], added: -1, tags: null, status: -1, + shared: false, packageorder: -1, stats: null, fids: null, diff --git a/module/web/static/js/utils/animations.js b/module/web/static/js/utils/animations.js index 245614ea7..798f69358 100644 --- a/module/web/static/js/utils/animations.js +++ b/module/web/static/js/utils/animations.js @@ -28,13 +28,17 @@ define(['jquery', 'underscore', 'transit'], function(jQuery, _) { // Shortcut to have a animation when element is added jQuery.fn.appendWithAnimation = function(element, animation) { var o = jQuery(this[0]); + element = jQuery(element); + if (animation === true) - o.hide(); + element.hide(); o.append(element); if (animation === true) - o.fadeIn(); + element.fadeIn(); + + element.calculateHeight(); return this; }; @@ -69,34 +73,6 @@ define(['jquery', 'underscore', 'transit'], function(jQuery, _) { return this; }; - // TODO: sloppy chaining - // - // in functions not possible without previous out - - jQuery.fn.zapIn = function(speed, easing, callback) { - var height = this.data('height') || '100%'; - this.transition({ - height: height, - scale: [1, 1], - opacity: 'show' - }, speed, easing, callback); - - }; - - jQuery.fn.zapOut = function(speed, easing, callback) { - if (!this.data('height')) { - var height = this.height(); - this.css({height: height}); - this.data('height', height); - } - this.transition({ - height: '0px', - scale: [1, 0], - opacity: 'hide' - }, speed, easing, callback); - - }; - jQuery.fn._transit = jQuery.fn.transit; // Overriding transit plugin to support hide and show diff --git a/module/web/static/js/views/abstract/itemView.js b/module/web/static/js/views/abstract/itemView.js index 7740abe5e..1c14e7dc3 100644 --- a/module/web/static/js/views/abstract/itemView.js +++ b/module/web/static/js/views/abstract/itemView.js @@ -24,8 +24,7 @@ define(['jquery', 'backbone', 'underscore'], function($, Backbone, _) { this.$el.slideDown(); }, - - delete: function(e) { + deleteItem: function(e) { if(e) e.stopPropagation(); this.model.destroy(); diff --git a/module/web/static/js/views/actionbarView.js b/module/web/static/js/views/actionbarView.js new file mode 100644 index 000000000..bdfb9ef7b --- /dev/null +++ b/module/web/static/js/views/actionbarView.js @@ -0,0 +1,28 @@ +define(['jquery', 'backbone', 'underscore', 'app'], + function($, Backbone, _, App) { + + // Renders the actionbar for the dashboard + return Backbone.View.extend({ + el: 'ul.actionbar', + + events: { + }, + + initialize: function() { + + this.$('.search-query').typeahead({ + minLength: 2, + source: this.getAutocompletion + }); + + }, + + render: function() { + }, + + getAutocompletion: function() { + return ["static", "autocompletion", "demo", "with", "some", "keywords", + "a very long proposal for autocompletion"]; + } + }); + }); \ No newline at end of file diff --git a/module/web/static/js/views/dashboardView.js b/module/web/static/js/views/dashboardView.js new file mode 100644 index 000000000..7f2b9809a --- /dev/null +++ b/module/web/static/js/views/dashboardView.js @@ -0,0 +1,133 @@ +define(['jquery', 'backbone', 'underscore', 'app', 'models/TreeCollection', + 'views/packageView', 'views/fileView', 'views/selectionView', 'views/actionbarView'], + function($, Backbone, _, App, TreeCollection, packageView, fileView, selectionView, actionbarView) { + + // Renders whole dashboard + return Backbone.View.extend({ + + el: '#content', + + events: { + 'click #show_active': 'filter' + }, + + //
    holding the packages + packageUL: null, + //
      displaying the files + fileUL: null, + // Current open files + files: null, + // True when loading animation is running + isLoading: false, + + initialize: function() { + var self = this; + this.tree = new TreeCollection(); + + var view = new selectionView(this.tree); + view = new actionbarView(); + + // When package is added we reload the data + App.vent.on('package:added', function() { + console.log('Package tree caught, package:added event'); + self.tree.fetch(); + }); + + // TODO file:added + + App.vent.on('dashboard:loading', _.bind(this.loading, this)); + App.vent.on('dashboard:contentReady', _.bind(this.contentReady, this)); + }, + + init: function() { + var self = this; + + // TODO: put in separated function + // TODO: order of elements? + // Init the tree and callback for package added + this.tree.fetch({success: function() { + self.render(); + self.tree.get('packages').on('add', function(pack) { + console.log('Package ' + pack.get('pid') + ' added to tree'); + self.appendPackage(pack, 0, true); + + }); + }}); + }, + + render: function() { + console.log('Render package list'); + var packs = this.tree.get('packages'); + this.files = this.tree.get('files'); + + this.packageUL = this.$('.package-list'); + packs.each(_.bind(this.appendPackage, this)); + + this.fileUL = this.$('.file-list'); + this.files.each(_.bind(this.appendFile, this)); + + return this; + }, + + // TODO sorting ?! + // Append a package to the list, index, animate it + appendPackage: function(pack, i, animation) { + var el = new packageView({model: pack}).render().el; + this.packageUL.appendWithAnimation(el, animation); + }, + + appendFile: function(file, i, animation) { + var el = new fileView({model: file}).render().el; + this.fileUL.appendWithAnimation(el, animation); + }, + + contentReady: function(files) { + this.files = files; + // show the files when no loading animation is running + if (!this.isLoading && this.files !== files) + this.show(); + }, + + loading: function(model) { + // nothing to load when it is already open + if (model && this.files === model.get('files')) + return; + + this.isLoading = true; + this.files = null; + var self = this; + // Render when the files are already set + this.fileUL.fadeOut({complete: function() { + if (self.files) + self.show(); + + self.isLoading = false; + }}); + }, + + failure: function() { + // TODO + }, + + show: function() { + this.fileUL.empty(); + this.files.each(_.bind(this.appendFile, this)); + this.fileUL.fadeIn(); + App.vent.trigger('dashboard:show', this.files); + }, + + // TODO: remove this debug stuff + toggle: false, + filter: function(e) { + var self = this; + this.tree.get('packages').each(function(item) { + if (!self.toggle) + item.trigger('filter:added'); + else + item.trigger('filter:removed'); + + }); + self.toggle ^= true; + } + }); + }); \ No newline at end of file diff --git a/module/web/static/js/views/packageTreeView.js b/module/web/static/js/views/packageTreeView.js deleted file mode 100644 index 41db0dc2c..000000000 --- a/module/web/static/js/views/packageTreeView.js +++ /dev/null @@ -1,115 +0,0 @@ -define(['jquery', 'backbone', 'underscore', 'app', 'models/TreeCollection', - 'views/packageView', 'views/fileView', 'views/selectionView'], - function($, Backbone, _, App, TreeCollection, packageView, fileView, selectionView) { - - // Renders whole PackageView - return Backbone.View.extend({ - - el: '#content', - - events: { - 'click #show_active': 'filter' - }, - - //
        holding the packages - packageUL: null, - //
          displaying the files - fileUL: null, - // current open model - opened: null, - // Current open files - files: null, - - initialize: function() { - var self = this; - this.tree = new TreeCollection(); - - var view = new selectionView(this.tree); - - // When package is added we reload the data - App.vent.on('package:added', function() { - console.log('Package tree caught, package:added event'); - self.tree.fetch(); - }); - - App.vent.on('dashboard:loading', _.bind(this.loading, this)); - App.vent.on('dashboard:show', _.bind(this.show, this)); - }, - - init: function() { - var self = this; - - // TODO: put in separated function - // TODO: order of elements? - // Init the tree and callback for package added - this.tree.fetch({success: function() { - self.render(); - self.tree.get('packages').on('add', function(pack) { - console.log('Package ' + pack.get('pid') + ' added to tree'); - self.appendPackage(pack, 0, true); - - }); - }}); - }, - - render: function() { - var packs = this.tree.get('packages'); - this.files = this.tree.get('files'); - - this.packageUL = this.$('.package-list'); - packs.each(_.bind(this.appendPackage, this)); - - this.fileUL = this.$('.file-list'); - this.files.each(_.bind(this.appendFile, this)); - - return this; - }, - - // TODO sorting ?! - // Append a package to the list, index, animate it - appendPackage: function(pack, i, animation) { - var el = new packageView({model: pack}).render().el; - this.packageUL.appendWithAnimation(el, animation); - }, - - appendFile: function(file, i, animation) { - var el = new fileView({model: file}).render().el; - this.fileUL.appendWithAnimation(el, animation); - }, - - loading: function(model) { - // nothing to load when it is already open -// if (this.opened === model) -// return; - // TODO: do not rerender already opened - this.opened = model; - this.files = null; -// this.fileUL.fadeOut(); - this.fileUL.empty(); - }, - - failure: function() { - // TODO - }, - - show: function(files) { - this.files = files; - files.each(_.bind(this.appendFile, this)); - this.fileUL.fadeIn(); - }, - - // TODO: remove this debug stuff - toggle: false, - filter: function(e) { - var self = this; - this.tree.get('packages').each(function(item) { - if (!self.toggle) - item.trigger('filter:added'); - else - item.trigger('filter:removed'); - - }); - self.toggle ^= true; - } - }); - }); \ No newline at end of file diff --git a/module/web/static/js/views/packageView.js b/module/web/static/js/views/packageView.js index 38b335dc9..eb3edccd8 100644 --- a/module/web/static/js/views/packageView.js +++ b/module/web/static/js/views/packageView.js @@ -9,7 +9,7 @@ define(['jquery', 'app', 'views/abstract/itemView', 'underscore'], template: _.compile($("#template-package").html()), events: { 'click .package-name': 'open', - 'click .iconf-trash': 'delete', + 'click .iconf-trash': 'deleteItem', 'click .select': 'select' }, @@ -38,11 +38,12 @@ define(['jquery', 'app', 'views/abstract/itemView', 'underscore'], unrender: function() { var self = this; - this.$el.zapOut(function() { + this.$el.slideUp(function() { self.destroy(); }); // TODO: display other package + App.vent.trigger('dashboard:loading', null); }, @@ -50,27 +51,15 @@ define(['jquery', 'app', 'views/abstract/itemView', 'underscore'], // Toggle expanding of packages expand: function(e) { e.preventDefault(); - var self = this; - - // this assumes the ul was created after item was rendered - if (!this.expanded) { - this.model.fetch({silent: true, success: function() { - self.render(true); - self.ul.animate({height: self.ul.data('height'), opacity: 'show'}); - self.expanded = true; - }}); - } else { - this.expanded = false; - this.ul.animate({height: 0, opacity: 'hide'}); - } }, open: function(e) { + e.preventDefault(); var self = this; App.vent.trigger('dashboard:loading', this.model); this.model.fetch({silent: true, success: function() { console.log('Package ' + self.model.get('pid') + ' loaded'); - App.vent.trigger('dashboard:show', self.model.get('files')); + App.vent.trigger('dashboard:contentReady', self.model.get('files')); }}); }, diff --git a/module/web/static/js/views/selectionView.js b/module/web/static/js/views/selectionView.js index 5cb22b776..673753cba 100644 --- a/module/web/static/js/views/selectionView.js +++ b/module/web/static/js/views/selectionView.js @@ -6,6 +6,13 @@ define(['jquery', 'backbone', 'underscore', 'app'], el: '#selection-area', template: _.compile($("#template-select").html()), + events: { + 'click .iconf-check': 'deselect', + 'click .iconf-pause': 'pause', + 'click .iconf-trash': 'trash', + 'click .iconf-refresh': 'refresh' + }, + // available packages tree: null, // selected files @@ -20,14 +27,26 @@ define(['jquery', 'backbone', 'underscore', 'app'], App.vent.on('dashboard:show', _.bind(this.set_files, this)); App.vent.on('package:selection', _.bind(this.render, this)); App.vent.on('file:selection', _.bind(this.render, this)); + + // TODO +// this.tree.get('packages').on('delete', _.bind(this.render, this)); }, - render: function() { - var files = 0; + get_files: function() { + var files = []; if (this.files) - files = this.files.where({selected: true}).length; + files = this.files.where({selected: true}); + + return files; + }, - var packs = this.tree.get('packages').where({selected: true}).length; + get_packs: function() { + return this.tree.get('packages').where({selected: true}); + }, + + render: function() { + var files = this.get_files().length; + var packs = this.get_packs().length; if (files + packs > 0) this.$el.html(this.template({files: files, packs: packs})); @@ -44,6 +63,38 @@ define(['jquery', 'backbone', 'underscore', 'app'], set_files: function(files) { this.files = files; this.render(); + }, + + deselect: function() { + this.get_files().map(function(file) { + file.set('selected', false); + }); + + this.get_packs().map(function(pack) { + pack.set('selected', false); + }); + + this.render(); + }, + + pause: function() { + // TODO + }, + + trash: function() { + this.get_files().map(function(file) { + file.destroy(); + }); + + this.get_packs().map(function(pack) { + pack.destroy(); + }); + + this.render(); + }, + + refresh: function() { + // TODO } }); }); \ No newline at end of file diff --git a/module/web/templates/default/dashboard.html b/module/web/templates/default/dashboard.html index 2dc29a583..1d4412846 100644 --- a/module/web/templates/default/dashboard.html +++ b/module/web/templates/default/dashboard.html @@ -8,7 +8,7 @@ {% endblock %} {% block require %} - App.initPackageTree(); + App.initDashboard(); {% endblock %} {% block head %} @@ -21,6 +21,7 @@ <% name %> +
          video @@ -29,7 +30,11 @@
          + <%= if shared %> + + <% else %> + <%/if%>
          @@ -75,11 +80,12 @@ <%= if packs %> <% packs %> packages <%/if %> - selected <%= if files %> <% files %> files <%/if %> + selected  |  +     @@ -90,7 +96,7 @@