User quota working on the front end.
authorCameron Ball <cameron@getapproved.com.au>
Fri, 5 Dec 2014 02:32:35 +0000 (10:32 +0800)
committerCameron Ball <cameron@getapproved.com.au>
Fri, 5 Dec 2014 02:32:35 +0000 (10:32 +0800)
19 files changed:
app/components/hello/hello-service.js
app/components/menu/menu-directive.js
app/components/menu/menu.html
app/components/messages/messagebox-controller.js [new file with mode: 0644]
app/components/messages/messagebox-directive.js [new file with mode: 0644]
app/components/simfiles/simfile-directive.js
app/components/simfiles/simfile.html
app/components/simfiles/simfiles-service.js
app/components/user/user-service.js
app/components/userMenu/userMenu-directive.js
app/components/userMenu/userMenu.html
app/divinelegy.css
app/divinelegy.js
app/grid.css
app/index.html
app/pages/packs/packs.html
app/pages/packs/packs.js
app/pages/simfiles/simfiles.html
bower.json

index 37302ee..739ff69 100644 (file)
@@ -40,7 +40,7 @@ factory("HelloService", ['rockEndpoint', '$http', '$location', '$q', function(ro
     
     hello.getAccessToken = function()
     {
-        return hello.utils.store('facebook').access_token;
+        return this.isLoggedIn() ? hello.utils.store('facebook').access_token : null;
     };
     
     hello.facebookLogin = function()
index 1daee1d..5987676 100644 (file)
@@ -1,30 +1,12 @@
 'use strict';
 
 //Module is defined in menu-controller.js so we only use angular.module(name) to retrieve and add to it.
-angular.module('DivinElegy.components.menu').
+angular.module('DivinElegy.components.menu', []).
         
-directive('menu', ['HelloService', 'UserService', function(HelloService, UserService
+directive('menu', [function(
 {
     return {
-        templateUrl: 'components/menu/menu.html',
-        link: function(scope, element){
-            HelloService.on('auth.login.userReady', function()
-            {
-                UserService.getCurrentUser().then(function(user)
-                {
-                    scope.welcomeMessage = 'Welcome, ' + user.displayName;
-                    scope.loggedIn = true;
-                    scope.$$phase || scope.$apply();
-                });
-            });
-            
-            HelloService.on('auth.logout', function()
-            {
-                scope.welcomeMessage = '';
-                scope.loggedIn = false;
-                scope.$$phase || scope.$apply();
-            });
-        }
+        templateUrl: 'components/menu/menu.html'
     };
 }]);
 
index e888cb6..5d32bc6 100644 (file)
@@ -1,10 +1,4 @@
-<ul class="menu" ng-controller="MenuController">
+<ul class="menu">
     <li><a href="#/">Home</a></li>
-    <li><a href="#/upload">Upload</a></li>
     <li><a href="#/simfiles">Simfiles</a></li>
-    <li>
-        {{welcomeMessage}}
-        <a href="#" ng-if="loggedIn" ng-click="doLogout()">logout</a>
-        <a href="#" ng-if="!loggedIn" ng-click="doLogin()">login</a>
-    </li>
 </ul>
\ No newline at end of file
diff --git a/app/components/messages/messagebox-controller.js b/app/components/messages/messagebox-controller.js
new file mode 100644 (file)
index 0000000..1f5e991
--- /dev/null
@@ -0,0 +1,45 @@
+'use strict';
+
+angular.module("DivinElegy.components.messages", ['ngSanitize'])
+
+.controller("MessageBoxController", ['$scope', function($scope)
+{
+    //message types are info, success, warning, error
+    
+    $scope.message = 'duh herro <a ng-click="willThisWork()">asdf</a>';
+    $scope.messageType = 'info';
+    $scope.hidden = false;
+        
+    $scope.hide = function()
+    {
+        $scope.hidden = true;
+    };
+    
+    $scope.$on('message.error', function(event, message)
+    {
+        $scope.message = message;
+        $scope.messageType = 'error';
+        $scope.hidden = false;
+    });
+    
+    $scope.$on('message.info', function(event, message)
+    {
+        $scope.message = message;
+        $scope.messageType = 'info';
+        $scope.hidden = false;
+    });
+    
+    $scope.$on('message.success', function(event, message)
+    {
+        $scope.message = message;
+        $scope.messageType = 'success';
+        $scope.hidden = false;
+    });
+    
+    $scope.$on('message.warning', function(event, message)
+    {
+        $scope.message = message;
+        $scope.messageType = 'warning';
+        $scope.hidden = false;
+    });
+}]);
\ No newline at end of file
diff --git a/app/components/messages/messagebox-directive.js b/app/components/messages/messagebox-directive.js
new file mode 100644 (file)
index 0000000..005def3
--- /dev/null
@@ -0,0 +1,30 @@
+'use strict';
+
+//Module is defined in menu-controller.js so we only use angular.module(name) to retrieve and add to it.
+angular.module('DivinElegy.components.messages').
+        
+directive('message', ['$compile', function ($compile)
+{
+    return function(scope, element, attrs)
+    {
+        scope.$watch(
+            function(scope)
+            {
+                // watch the 'compile' expression for changes
+                return scope.$eval(attrs.message);
+            },
+            function(value)
+            {
+                // when the 'compile' expression changes
+                // assign it into the current DOM
+                element.html(value);
+
+                // compile the new DOM and link it to the current
+                // scope.
+                // NOTE: we only compile .childNodes so that
+                // we don't get into infinite loop compiling ourselves
+                $compile(element.contents())(scope);
+            }
+        );
+    };
+}]);
\ No newline at end of file
index 8c92113..cb8941f 100644 (file)
@@ -17,6 +17,7 @@ directive('simfile', function()
             bpmChanges: '=',
             bgChanges: '=',
             fgChanges: '=',
+            size: '=',
             download: '='
         },
         templateUrl: 'components/simfiles/simfile.html'
index fabd97c..d5f7cf9 100644 (file)
         <th>FGChanges:</th>
         <td>{{fgChanges}}</td>
     </tr>
+    <tr ng-if="size">
+        <th>Size:</th>
+        <td>{{size}}</td>
+    </tr>
     <tr ng-if="download">
         <th>Download:</th>
         <td><a href="{{rockEndpoint}}{{download}}">DivinElegy</a></td>
index 5628e38..577f1a7 100644 (file)
@@ -2,10 +2,10 @@
 
 angular.module("DivinElegy.components.simfiles", ['DivinElegy.components.config']).
       
-factory("SimfileService", ['rockEndpoint', '$http', '$q', function(rockEndpoint, $http, $q)
+factory("SimfileService", ['rockEndpoint', '$http', '$q', 'HelloService', function(rockEndpoint, $http, $q, HelloService)
 {
     var simfileAPI = {};
-    
+    var token = HelloService.getAccessToken();
     simfileAPI.getSimfiles = function()
     {
         var deferred = $q.defer();
@@ -16,7 +16,8 @@ factory("SimfileService", ['rockEndpoint', '$http', '$q', function(rockEndpoint,
         } else {
             $http({
                 url: rockEndpoint + "simfiles/",
-                method: "GET"
+                method: "GET",
+                params: {token: token}
             }).
             success(function (data)
             {
@@ -38,7 +39,8 @@ factory("SimfileService", ['rockEndpoint', '$http', '$q', function(rockEndpoint,
         } else {
             $http({
                 url: rockEndpoint + "simfiles/",
-                method: "GET"
+                method: "GET",
+                params: {token: token}
             }).
             success(function (data)
             {
index 565c25f..ecbfd41 100644 (file)
@@ -2,16 +2,16 @@
 
 angular.module("DivinElegy.components.user", ['DivinElegy.components.config', 'DivinElegy.components.hello']).
       
-factory("UserService", ['rockEndpoint', '$http', '$q', 'HelloService', function(rockEndpoint, $http, $q, HelloService)
+factory("UserService", ['$rootScope', 'rockEndpoint', '$http', '$q', 'HelloService', function($rootScope, rockEndpoint, $http, $q, HelloService)
 {
     var UserService = {};
     UserService.userCache = {};
     
-    UserService.getUser = function(facebookId)
+    UserService.getUser = function(facebookId, skipCache)
     {
         var deferred = $q.defer();
-        
-        if(this.userCache[facebookId])
+        var token = HelloService.getAccessToken();
+        if(this.userCache[facebookId] && !skipCache)
         {
             this.userCache[facebookId]['fromCache'] = true;
             deferred.resolve(this.userCache[facebookId]);
@@ -20,15 +20,25 @@ factory("UserService", ['rockEndpoint', '$http', '$q', 'HelloService', function(
 
         $http({
             url: rockEndpoint + "user/" + facebookId,
-            method: "GET"
+            method: "GET",
+            params: {token: token}
         }).
         success(function (data)
         {
             UserService.userCache[facebookId] = data;
             deferred.resolve(data);
+            //XXX: kinda hacky, but this way everything that has stuff pulled out of this service can update
+            //we assume if the cache was skipped we're updating
+            if(skipCache)
+            {
+                window.hello.emit('auth.login.userReady');
+            }
+        }).
+        error(function(data, status)
+        {
+            $rootScope.$broadcast('message.error', 'Uh oh, something went really wrong. Try refreshing the page.'); 
         });
-        
-        
+
         return deferred.promise;
     };
 
@@ -47,5 +57,19 @@ factory("UserService", ['rockEndpoint', '$http', '$q', 'HelloService', function(
         }
     };
          
+    UserService.updateCache = function()
+    {
+        if (!this.facebookId)
+        {
+            HelloService.getFacebookId().then(function(fbId)
+            {
+                UserService.facebookId = fbId;
+                UserService.getUser(fbId, true);
+            });
+        } else {
+            this.getUser(this.facebookId, true);
+        }
+    };
+         
     return UserService;
 }]);
\ No newline at end of file
index 68d61e8..343aeb0 100644 (file)
@@ -1,21 +1,39 @@
 'use strict'
 
-angular.module('DivinElegy.components.userMenu', ['DivinElegy.components.hello']).
+angular.module('DivinElegy.components.userMenu', ['DivinElegy.components.user', 'DivinElegy.components.hello']).
         
-directive('userMenu', ['HelloService', function(HelloService) 
+directive('userMenu', ['HelloService', 'UserService', function(HelloService, UserService) 
 {
     return {
         templateUrl: 'components/userMenu/userMenu.html',
         link: function(scope, element){
-            HelloService.on('auth.login', function()
+            scope.doLogin = function()
             {
-                scope.showMenu = true;
-                scope.$$phase || scope.$apply();
+                HelloService.facebookLogin();
+            };
+
+            scope.doLogout = function()
+            {
+                HelloService.logout('facebook');
+            };
+            
+            HelloService.on('auth.login.userReady', function()
+            {
+                UserService.getCurrentUser().then(function(user)
+                {
+                    console.log(user);
+                    scope.welcomeMessage = 'Welcome, ' + user.displayName;
+                    scope.quota = user.quota;
+                    scope.quotaRemaining = user.quotaRemaining;
+                    scope.loggedIn = true;
+                    scope.$$phase || scope.$apply();
+                });
             });
             
             HelloService.on('auth.logout', function()
             {
-                scope.showMenu = false;
+                scope.welcomeMessage = '';
+                scope.loggedIn = false;
                 scope.$$phase || scope.$apply();
             });
         }
index 2cebf57..3182f7d 100644 (file)
@@ -1,15 +1,30 @@
-<div id="usermenu" ng-if="showMenu">
+<div id="usermenu">
     <ul>
-        <li>Public Profile</li>
-        <li>Account Settings</li>
-    </ul>
-    <ul>
-        <li>My Uploads</li>
-        <li>My Favourite Files</li>
-        <li>My Favourite Uploaders</li>
-        <li>My Followers</li>
-    </ul>
-    <ul>
-        <li>All Members</li>
+        <li>
+            {{welcomeMessage}}
+            <a href="#" ng-if="loggedIn" ng-click="doLogout()">logout</a>
+            <a href="#" ng-if="!loggedIn" ng-click="doLogin()">login</a>
+        </li>
     </ul>
+    <div ng-if="loggedIn">
+        <br />
+        <ul>
+            <li>Public Profile</li>
+            <li>Account Settings</li>
+        </ul>
+        <br />
+        <ul>
+            <li>My Uploads</li>
+            <li>My Favourite Files</li>
+            <li>My Favourite Uploaders</li>
+            <li>My Followers</li>
+        </ul>
+        <br />
+        <ul>
+            <li>All Members</li>
+        </ul>
+        <br />
+        <h1>My Quota</h1>
+        {{quotaRemaining}} of {{quota}} remaining
+    </div>
 </div>
\ No newline at end of file
index 9f35efa..2667117 100644 (file)
@@ -36,11 +36,68 @@ body {
 
 #navigation,
 #controlPanel {
-    margin-top: 100px;
+    margin-top: 60px;
 }
 
 #post {
-    margin-top: 56px;
+    margin-top: 16px;
+}
+
+#message-box {
+    text-align: center;
+    font-weight: bold;
+    margin-top: 40px;
+    padding: 10px;
+    background-color: #bde5f8;
+    color: #3d7cb2;
+    border: 3px solid #3d7cb2;
+    border-radius: 10px;
+    -moz-border-radius: 10px;
+    -webkit-border-radius: 10px;
+}
+
+#message-box .ok {
+    display: inline-block;
+    text-align: center;
+    width: 32px;
+    border: 2px solid black;
+    padding: 2px;
+    margin-left: 10px;
+    border-radius: 10px;
+    -moz-border-radius: 10px;
+    -webkit-border-radius: 10px;
+}
+
+.de-link,
+#message-box .ok:hover {
+    cursor: pointer;
+}
+
+#message-box.hidden {
+    visibility: hidden;
+}
+
+#message-box.info {
+    color: #3d7cb2;
+    border: 3px solid #3d7cb2;
+}
+
+#message-box.success {
+    background-color: #dff2bf;
+    color: #a5c084;
+    border: 2px solid #a5c084;
+}
+
+#message-box.warning {
+    background-color: #feefb3;
+    color: #c9aa73;
+    border: 2px solid #c9aa73;
+}
+
+#message-box.error {
+    background-color: #ffbaba;
+    color: #d20000;
+    border: 2px solid #d20000;
 }
 
 .simfileListing {
index 7c7cb1d..c4861e2 100644 (file)
@@ -7,6 +7,7 @@ angular.module('DivinElegy', [
   'DivinElegy.components.menu',
   'DivinElegy.components.userMenu',
   'DivinElegy.components.simfiles',
+  'DivinElegy.components.messages',
   'DivinElegy.pages.index',
   'DivinElegy.pages.upload',
   'DivinElegy.pages.simfiles',
@@ -40,6 +41,14 @@ config(['$routeProvider', '$locationProvider', function($routeProvider) {
         templateUrl: 'pages/packs/packs.html',
         controller: 'PackController'
     }).
+    when('/packs/test',
+    {
+        resolve: {
+            load: function () {
+                console.log("hello");
+            }
+        }
+    }).
     otherwise({redirectTo: '/'});
 }]).
         
index 44eefb5..cb54cf4 100644 (file)
-.container_15 {\r
-       WIDTH: 1200px; MARGIN-LEFT: auto; MARGIN-RIGHT: auto\r
+.container {\r
+       WIDTH: 1008px; MARGIN-LEFT: auto; MARGIN-RIGHT: auto\r
 }\r
-.grid_1 {\r
-       POSITION: relative; DISPLAY: inline; FLOAT: left; MARGIN-LEFT: 10px; MARGIN-RIGHT: 10px\r
+.box_side {\r
+       POSITION: relative; DISPLAY: inline; FLOAT: left; MARGIN-LEFT: 0px; MARGIN-RIGHT: 0px\r
 }\r
-.grid_2 {\r
-       POSITION: relative; DISPLAY: inline; FLOAT: left; MARGIN-LEFT: 10px; MARGIN-RIGHT: 10px\r
+\r
+.box_main {\r
+       POSITION: relative; DISPLAY: inline; FLOAT: left; MARGIN-LEFT: 5px; MARGIN-RIGHT: 5px\r
 }\r
-.grid_3 {\r
-       POSITION: relative; DISPLAY: inline; FLOAT: left; MARGIN-LEFT: 10px; MARGIN-RIGHT: 10px\r
+\r
+.container .box_side {\r
+       WIDTH: 150px\r
 }\r
-.grid_4 {\r
-       POSITION: relative; DISPLAY: inline; FLOAT: left; MARGIN-LEFT: 10px; MARGIN-RIGHT: 10px\r
+.container .box_main {\r
+       WIDTH: 698px\r
 }\r
-.grid_5 {\r
-       POSITION: relative; DISPLAY: inline; FLOAT: left; MARGIN-LEFT: 10px; MARGIN-RIGHT: 10px\r
-}\r
-.grid_6 {\r
-       POSITION: relative; DISPLAY: inline; FLOAT: left; MARGIN-LEFT: 10px; MARGIN-RIGHT: 10px\r
-}\r
-.grid_7 {\r
-       POSITION: relative; DISPLAY: inline; FLOAT: left; MARGIN-LEFT: 10px; MARGIN-RIGHT: 10px\r
-}\r
-.grid_8 {\r
-       POSITION: relative; DISPLAY: inline; FLOAT: left; MARGIN-LEFT: 10px; MARGIN-RIGHT: 10px\r
-}\r
-.grid_9 {\r
-       POSITION: relative; DISPLAY: inline; FLOAT: left; MARGIN-LEFT: 10px; MARGIN-RIGHT: 10px\r
-}\r
-.grid_10 {\r
-       POSITION: relative; DISPLAY: inline; FLOAT: left; MARGIN-LEFT: 10px; MARGIN-RIGHT: 10px\r
-}\r
-.grid_11 {\r
-       POSITION: relative; DISPLAY: inline; FLOAT: left; MARGIN-LEFT: 10px; MARGIN-RIGHT: 10px\r
-}\r
-.grid_12 {\r
-       POSITION: relative; DISPLAY: inline; FLOAT: left; MARGIN-LEFT: 10px; MARGIN-RIGHT: 10px\r
-}\r
-.grid_15 {\r
-       POSITION: relative; DISPLAY: inline; FLOAT: left; MARGIN-LEFT: 10px; MARGIN-RIGHT: 10px\r
-}\r
-.alpha {\r
-       MARGIN-LEFT: 0px\r
-}\r
-.omega {\r
-       MARGIN-RIGHT: 0px\r
-}\r
-.container_15 .grid_1 {\r
-       WIDTH: 60px\r
-}\r
-.container_15 .grid_2 {\r
-       WIDTH: 140px\r
-}\r
-.container_15 .grid_3 {\r
-       WIDTH: 220px\r
-}\r
-.container_15 .grid_4 {\r
-       WIDTH: 300px\r
-}\r
-.container_15 .grid_5 {\r
-       WIDTH: 380px\r
-}\r
-.container_15 .grid_6 {\r
-       WIDTH: 460px\r
-}\r
-.container_15 .grid_7 {\r
-       WIDTH: 540px\r
-}\r
-.container_15 .grid_8 {\r
-       WIDTH: 620px\r
-}\r
-.container_15 .grid_9 {\r
-       WIDTH: 700px\r
-}\r
-.container_15 .grid_10 {\r
-       WIDTH: 780px\r
-}\r
-.container_15 .grid_11 {\r
-       WIDTH: 860px\r
-}\r
-.container_15 .grid_12 {\r
-       WIDTH: 940px\r
-}\r
-.container_15 .grid_15 {\r
-       WIDTH: 1180px\r
-}\r
-.container_15 .prefix_1 {\r
-       PADDING-LEFT: 80px\r
-}\r
-.container_15 .prefix_2 {\r
-       PADDING-LEFT: 160px\r
-}\r
-.container_15 .prefix_3 {\r
-       PADDING-LEFT: 240px\r
-}\r
-.container_15 .prefix_4 {\r
-       PADDING-LEFT: 320px\r
-}\r
-.container_15 .prefix_5 {\r
-       PADDING-LEFT: 400px\r
-}\r
-.container_15 .prefix_6 {\r
-       PADDING-LEFT: 480px\r
-}\r
-.container_15 .prefix_7 {\r
-       PADDING-LEFT: 560px\r
-}\r
-.container_15 .prefix_8 {\r
-       PADDING-LEFT: 640px\r
-}\r
-.container_15 .prefix_9 {\r
-       PADDING-LEFT: 720px\r
-}\r
-.container_15 .prefix_10 {\r
-       PADDING-LEFT: 800px\r
-}\r
-.container_15 .prefix_11 {\r
-       PADDING-LEFT: 880px\r
-}\r
-.container_15 .suffix_1 {\r
-       PADDING-RIGHT: 80px\r
-}\r
-.container_15 .suffix_2 {\r
-       PADDING-RIGHT: 160px\r
-}\r
-.container_15 .suffix_3 {\r
-       PADDING-RIGHT: 240px\r
-}\r
-.container_15 .suffix_4 {\r
-       PADDING-RIGHT: 320px\r
-}\r
-.container_15 .suffix_5 {\r
-       PADDING-RIGHT: 400px\r
-}\r
-.container_15 .suffix_6 {\r
-       PADDING-RIGHT: 480px\r
-}\r
-.container_15 .suffix_7 {\r
-       PADDING-RIGHT: 560px\r
-}\r
-.container_15 .suffix_8 {\r
-       PADDING-RIGHT: 640px\r
-}\r
-.container_15 .suffix_9 {\r
-       PADDING-RIGHT: 720px\r
-}\r
-.container_15 .suffix_10 {\r
-       PADDING-RIGHT: 800px\r
-}\r
-.container_15 .suffix_11 {\r
-       PADDING-RIGHT: 880px\r
-}\r
-.container_15 .push_1 {\r
-       LEFT: 80px\r
-}\r
-.container_15 .push_2 {\r
-       LEFT: 160px\r
-}\r
-.container_15 .push_3 {\r
-       LEFT: 240px\r
-}\r
-.container_15 .push_4 {\r
-       LEFT: 320px\r
-}\r
-.container_15 .push_5 {\r
-       LEFT: 400px\r
-}\r
-.container_15 .push_6 {\r
-       LEFT: 480px\r
-}\r
-.container_15 .push_7 {\r
-       LEFT: 560px\r
-}\r
-.container_15 .push_8 {\r
-       LEFT: 640px\r
-}\r
-.container_15 .push_9 {\r
-       LEFT: 720px\r
-}\r
-.container_15 .push_10 {\r
-       LEFT: 800px\r
-}\r
-.container_15 .push_11 {\r
-       LEFT: 880px\r
-}\r
-.container_15 .pull_1 {\r
-       LEFT: -80px\r
-}\r
-.container_15 .pull_2 {\r
-       LEFT: -160px\r
-}\r
-.container_15 .pull_3 {\r
-       LEFT: -240px\r
-}\r
-.container_15 .pull_4 {\r
-       LEFT: -320px\r
-}\r
-.container_15 .pull_5 {\r
-       LEFT: -400px\r
-}\r
-.container_15 .pull_6 {\r
-       LEFT: -480px\r
-}\r
-.container_15 .pull_7 {\r
-       LEFT: -560px\r
-}\r
-.container_15 .pull_8 {\r
-       LEFT: -640px\r
-}\r
-.container_15 .pull_9 {\r
-       LEFT: -720px\r
-}\r
-.container_15 .pull_10 {\r
-       LEFT: -800px\r
-}\r
-.container_15 .pull_11 {\r
-       LEFT: -880px\r
+\r
+.container .box_full {\r
+    width: 1008px;\r
 }\r
+\r
 .clear {\r
        WIDTH: 0px; DISPLAY: block; HEIGHT: 0px; VISIBILITY: hidden; CLEAR: both; OVERFLOW: hidden\r
 }\r
index 55ff012..0567668 100644 (file)
         <script src="bower_components/angular/angular.js"></script>
         <script src="bower_components/angular-route/angular-route.js"></script>
         <script src="bower_components/angular-file-upload/angular-file-upload.js"></script>
+        <script src="bower_components/angular-sanitize/angular-sanitize.js"></script>
         <script class="pre" src="bower_components/hello/dist/hello.all.js"></script>
 
         <!-- components -->
         <script src="components/config/rockEndpoint-value.js"></script>
         <script src="components/hello/hello-service.js"></script>
         <script src="components/user/user-service.js"></script>
-        <script src="components/menu/menu-controller.js"></script>
         <script src="components/menu/menu-directive.js"></script>
         <script src="components/userMenu/userMenu-directive.js"></script>
         <script src="components/simfiles/simfiles-service.js"></script>
         <script src="components/simfiles/simfile-directive.js"></script>
+        <script src="components/messages/messagebox-controller.js"></script>
+        <script src="components/messages/messagebox-directive.js"></script>
         
         <!-- pages -->
         <script src="pages/index/index.js"></script>
         <script src="divinelegy.js"></script>  
     </head>
     <body>
-        <div class="container_15">
-            <div class="grid_3">
+        <div class="container">
+            <div class="box_full">
+                <div id="message-box" ng-controller="MessageBoxController" ng-class="{'info' : messageType == 'info',
+                                                                                      'warning' : messageType == 'warning',
+                                                                                      'error' : messageType == 'error',
+                                                                                      'success' : messageType == 'success',
+                                                                                      'hidden' : hidden}">
+                    <span message="message"></span> <span class="ok" ng-click="hide()">OK</span>
+                </div>
+            </div>
+            <div class="box_side alpha">
                 <div id="navigation" class="panel" menu></div>
             </div>
 
-            <div class="grid_9">
+            <div class="box_main">
                 <div id="post" class="panel" ng-view>
                     <!-- extreme hard rock for DivinElegy gets loaded in here. -->
                 </div>
             </div>
 
-            <div class="grid_3">
+            <div class="box_side omega">
                 <div id="controlPanel" class="panel" user-menu></div>
             </div>
         </div>
index d965293..1928892 100644 (file)
@@ -36,12 +36,17 @@ BPM changes: <input type="checkbox" ng-model="bpmChangesFilterKeyword">
                     <th>Contributors:</th>\r
                     <td>{{contributors}}</td>\r
                 </tr>\r
+                <tr ng-if="pack.size">\r
+                    <th>Size:</th>\r
+                    <td>{{pack.size}}</td>\r
+                </tr>\r
                 <tr ng-if="pack.mirrors">\r
                     <th>Downloads:</th>\r
                     <td>\r
                         <ul>\r
                             <li class="mirrorListing" ng-repeat="mirror in pack.mirrors">\r
-                                <a href="{{mirror.uri}}">{{mirror.source}}{{$last ? '' : ', '}}</a>\r
+                                <a ng-if="mirror.source == 'DivinElegy'" ng-click="downloadFromDe(pack)" class="de-link">{{mirror.source}}</a>\r
+                                <a ng-if="mirror.source != 'DivinElegy'" href="{{mirror.uri}}">{{mirror.source}}</a>\r
                             </li>\r
                         </ul>\r
                     </td>\r
index d5f69ff..e8a2c5e 100644 (file)
@@ -1,8 +1,8 @@
 'use strict';
 
-angular.module("DivinElegy.pages.packs", ["DivinElegy.components.simfiles","DivinElegy.components.config"])
+angular.module("DivinElegy.pages.packs", ["DivinElegy.components.simfiles","DivinElegy.components.user","DivinElegy.components.config"])
 
-.controller("PackController", ['$scope', 'rockEndpoint', 'SimfileService', function($scope, rockEndpoint, SimfileService)
+.controller("PackController", ['$scope', '$rootScope', 'rockEndpoint', 'SimfileService', 'UserService', 'HelloService', function($scope, $rootScope, rockEndpoint, SimfileService, UserService, HelloService)
 {
     $scope.rockEndpoint = rockEndpoint;
     $scope.activeListings = [];
@@ -17,6 +17,56 @@ angular.module("DivinElegy.pages.packs", ["DivinElegy.components.simfiles","Divi
     $scope.bpmChangesFilterKeyword = null;
     $scope.simfileList = [];
     
+    var filesizeBytes = function(size)  
+    {  
+        //units are already bytes
+        if(!isNaN(size.substring(size.length-2, size.length-1)))
+        {
+            return size.substring(0, size.length-1);
+        }
+
+        var units = size.substring(size.length-2, size.length);
+        var size = size.substring(0, size.length-2);
+        var fileUnits = ["B", "kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];  
+
+        for(var i=0; i<fileUnits.length; i++)
+        {
+            if(fileUnits[i] == units) { break; }
+            size = size*1000;
+        }
+
+        return Number(size);  
+    };
+
+    $scope.downloadFromDe = function(pack)
+    {        
+        UserService.getCurrentUser().then(function(user)
+        {
+            var size = filesizeBytes(pack.size);
+            var quotaRemaining = filesizeBytes(user.quotaRemaining);
+            
+            if(quotaRemaining < size)
+            {
+                $rootScope.$broadcast('message.error', 'Sorry, you do not have enough quota to download that file. Quota resets at 00:00 UTC+0'); 
+            } else {
+                //TODO: Maybe access token should be in user obj?
+                var url = rockEndpoint + '' + pack.mirrors[0].uri + '?token=' + HelloService.getAccessToken(); //0th mirror will always be de
+                $rootScope.$broadcast('message.warning', 'You are about to download ' + pack.title + ' which is ' + pack.size + '. Your current quota is ' + user.quotaRemaining + ' click <a ng-click="updateUserCache()" href="' + url + '">here</a> to confirm.'); 
+            }
+        });
+    };
+    
+    $rootScope.updateUserCache = function()
+    {
+        //TODO: This may not be the best way to do this, but basically when this function
+        //is called by ng-click, rock.de hasn't had time to log the download yet so if
+        //we update the cache straight away, we still get the old user quota. Waiting
+        //a second gives it time to sort itself out.
+        setTimeout(function() {
+            UserService.updateCache();
+        },1000);
+    };
+        
     $scope.openListing = function(listing)
     {
         if($scope.isListingActive(listing))
index dfd6d4e..5632fc4 100644 (file)
@@ -32,7 +32,8 @@ BPM changes: <input type="checkbox" ng-model="bpmChangesFilterKeyword">
                      steps="simfile.steps"\r
                      bpm-changes="simfile.bpmChanges"\r
                      bg-changes="simfile.bgChanges"\r
-                     fg-changes="simfile.fgChanges"\r
+                     fg-changes="simfile.fgChanges",\r
+                     size="simfile.size",\r
                      download="simfile.download"\r
             />\r
         </div>\r
index a5feb7c..d39bc71 100644 (file)
@@ -12,6 +12,7 @@
     "angular-mocks": "~1.2.x",
     "html5-boilerplate": "~4.3.0",
     "angular-file-upload": "1.1.1",
-    "hello": "1.2.1"
+    "hello": "1.2.1",
+    "angular-sanitize": "1.3.x"
   }
 }