diff options
| author | 2013-02-20 12:00:22 +0100 | |
|---|---|---|
| committer | 2013-02-20 12:00:22 +0100 | |
| commit | 1e1b64539144006c59c7b705700fc7f34c7a26b1 (patch) | |
| tree | ebae99f037953469d4437331763c0c38d41e9511 /module | |
| parent | integrated new package view (diff) | |
| download | pyload-1e1b64539144006c59c7b705700fc7f34c7a26b1.tar.xz | |
more animation for dashboard
Diffstat (limited to 'module')
| -rw-r--r-- | module/api/ConfigApi.py | 2 | ||||
| -rw-r--r-- | module/api/FileApi.py | 6 | ||||
| -rw-r--r-- | module/database/DatabaseBackend.py | 1 | ||||
| -rw-r--r-- | module/database/FileDatabase.py | 46 | ||||
| -rw-r--r-- | module/datatypes/PyPackage.py | 10 | ||||
| -rw-r--r-- | module/remote/pyload.thrift | 10 | ||||
| -rw-r--r-- | module/remote/ttypes.py | 29 | ||||
| -rw-r--r-- | module/remote/ttypes_debug.py | 11 | ||||
| -rw-r--r-- | module/web/static/css/default/dashboard.less | 5 | ||||
| -rw-r--r-- | module/web/static/css/default/style.less | 11 | ||||
| -rw-r--r-- | module/web/static/js/default.js | 10 | ||||
| -rw-r--r-- | module/web/static/js/models/Package.js | 1 | ||||
| -rw-r--r-- | module/web/static/js/utils/animations.js | 36 | ||||
| -rw-r--r-- | module/web/static/js/views/abstract/itemView.js | 3 | ||||
| -rw-r--r-- | module/web/static/js/views/actionbarView.js | 28 | ||||
| -rw-r--r-- | module/web/static/js/views/dashboardView.js (renamed from module/web/static/js/views/packageTreeView.js) | 246 | ||||
| -rw-r--r-- | module/web/static/js/views/packageView.js | 21 | ||||
| -rw-r--r-- | module/web/static/js/views/selectionView.js | 59 | ||||
| -rw-r--r-- | module/web/templates/default/dashboard.html | 12 | 
19 files changed, 324 insertions, 223 deletions
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 @@ -77,6 +77,12 @@ class FileApi(ApiComponent):          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<string> tags,    11: PackageStatus status, -  12: i16 packageorder, -  13: PackageStats stats, -  14: list<FileID> fids, -  15: list<PackageID> pids, +  12: bool shared, +  13: i16 packageorder, +  14: PackageStats stats, +  15: list<FileID> fids, +  16: list<PackageID> 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<string> getAutocompletion(1: string pattern),    TreeCollection findPackages(1: list<string> 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/packageTreeView.js b/module/web/static/js/views/dashboardView.js index 41db0dc2c..7f2b9809a 100644 --- a/module/web/static/js/views/packageTreeView.js +++ b/module/web/static/js/views/dashboardView.js @@ -1,115 +1,133 @@ -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'
 -            },
 -
 -            // <ul> holding the packages
 -            packageUL: null,
 -            // <ul> 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;
 -            }
 -        });
 +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' +            }, + +            // <ul> holding the packages +            packageUL: null, +            // <ul> 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/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 @@          <span class="package-name">
          <% name %>
          </span>
 +
          <div class="package-frame">
              <div class="tag-area">
                  <span class="badge badge-success"><i class="iconf-tag"></i>video</span>
 @@ -29,7 +30,11 @@              <div class="package-indicator">
                  <i class="iconf-pause"></i>
                  <i class="iconf-refresh"></i>
 +                <%= if shared %>
 +                <i class="iconf-eye-open"></i>
 +                <% else %>
                  <i class="iconf-eye-close"></i>
 +                <%/if%>
                  <i class="iconf-trash"></i>
                  <i class="iconf-chevron-down"></i>
              </div>
 @@ -75,11 +80,12 @@          <%= if packs %>
          <% packs %> packages
          <%/if %>
 -        selected
          <%= if files %>
          <% files %> files
          <%/if %>
 +        selected
           | 
 +        <i class="iconf-pause"></i> 
          <i class="iconf-trash"></i> 
          <i class="iconf-refresh"></i>
      </script>
 @@ -90,7 +96,7 @@      <ul class="actionbar nav nav-pills span9">
          <li>
              <ul class="breadcrumb">
 -                <li><a href="#">{{ _("Home") }}</a> <span class="divider">/</span></li>
 +                <li><a href="#">{{ _("Local") }}</a> <span class="divider">/</span></li>
                  <li class="active">Data</li>
              </ul>
          </li>
  | 
