Add some basic sorts. Fixes #9
authorCameron Ball <cameron@getapproved.com.au>
Tue, 19 May 2015 08:28:41 +0000 (16:28 +0800)
committerCameron Ball <cameron@getapproved.com.au>
Tue, 19 May 2015 08:28:41 +0000 (16:28 +0800)
app/css/divinelegy.css
app/pages/packs/packs.html
app/pages/packs/packs.js

index db58345..0dd470d 100644 (file)
@@ -33,11 +33,17 @@ table {
     background: rgba(255,255,255,0.05);
     border: 2px solid #000000;
     margin: 0px 2px 0px 2px;
-    border-radius: 10px;
-    -moz-border-radius: 10px;
-    -webkit-border-radius: 10px;
+    border-radius: 10px 10px 0px 10px;
+    -moz-border-radius: 10px 10px 0px 10px;
+    -webkit-border-radius: 10px 10px 0px 10px;
     padding-top: 8px;
-    margin-bottom: 20px;
+    height:90px;
+    margin-bottom: 90px;
+
+}
+
+#filters-wrapper {
+    display: inline-block;
 }
 
 input[type="text"], select {
@@ -70,10 +76,63 @@ input[type="checkbox"] {
     margin-bottom: 8px;
 }
 
-#text-filters input:last-child, #select-filters select:last-child {
+#text-filters input:last-child, #select-filters select:last-child, #sorts select, #sorts input {
     margin-right: 0px !important;
 }
 
+#filters #sorts {
+    text-align: right;
+    border: 2px solid #000000;
+    border-radius: 0px 0px 10px 10px;
+    -webkit-border-radius: 0px 0px 10px 10px;
+    -moz-border-radius: 0px 0px 10px 10px;
+    padding-right: 18px;
+    margin-right: -20px;
+    margin-left: 496px;
+    
+    /*
+        XXX: Tricky: Other divs just use transparency to get their BG colour
+        from underneath. We can't do that here as I need to cover the border
+        from the filters above. Find a better solution?
+    */
+    background-color: #263544;
+    border-top: none;
+    position: relative;
+}
+
+#filters #sorts input[type=checkbox] {
+    vertical-align: -3px;
+}
+
+#filters #sorts:before {
+content: ' ';
+  padding-right: 10px;
+  position: absolute;
+  top: 2px;
+  left: -22px;
+  border: 2px solid #000000;
+  border-radius: 0px 6px 0px 0px;
+  border-left: none;
+  border-bottom: none;
+  height: 10px;
+  width: 10px;
+    
+}
+
+#filters #sorts:after {
+    content: ' ';
+    padding-right: 10px;
+    position: absolute;
+    top: -2px;
+    left: -20px;
+    border: 4px solid #263544;
+    border-radius: 0px 10px 0px 0px;
+    border-left: none;
+    border-bottom: none;
+    height: 10px;
+    width: 10px;
+}
+
 #navigation table {
     border-collapse: separate;
     border-spacing: 0 5px;
index f33c414..f56eea5 100644 (file)
@@ -1,46 +1,57 @@
 <div ng-if="packList && packList.length" id="filters">\r
-    <div id="text-filters">\r
-        <input type="text" ng-model="$parent.packTitleFilterKeyword" placeholder="Pack Title" typeahead="pack.title for pack in packList | filter:$viewValue | limitTo:8"/>\r
-        <input type="text" ng-model="$parent.artistFilterKeyword" placeholder="Song Artist" typeahead="artist for artist in allSongArtists | filter:$viewValue | limitTo:8" />\r
-        <input type="text" ng-model="$parent.songTitleFilterKeyword" placeholder="Song Title" typeahead="song for song in allSongTitles | filter:$viewValue | limitTo:8" />\r
-        <input type="text" ng-model="$parent.stepArtistFilterKeyword" placeholder="Step Artist" typeahead="contributor for contributor in allContributors | filter:$viewValue | limitTo:8" />\r
-        <input type="text" ng-model="$parent.ratingFilterKeyword" placeholder="Block Rating"/>\r
-    </div>\r
-    <div id="select-filters">\r
-        <select ng-model="$parent.modeFilterKeyword">\r
-            <option value="Any" disabled selected>Mode</option>\r
-            <option value="Any">Any</option>\r
-            <option value="single">Single</option>\r
-            <option value="double">Double</option>\r
-        </select>\r
-        <select ng-model="$parent.difficultyFilterKeyword">\r
-            <option value="Any" disabled selected>Difficulty</option>\r
-            <option value="Any">Any</option>\r
-            <option value="Novice">Novice</option>\r
-            <option value="Easy">Easy</option>\r
-            <option value="Medium">Medium</option>\r
-            <option value="Hard">Hard</option>\r
-            <option value="Expert">Expert</option>\r
-            <option value="Edit">Edit</option>\r
-        </select>\r
-        <select ng-model="$parent.fgChangesFilterKeyword">\r
-            <option value="Any" disabled selected>FG Changes</option>\r
-            <option value="Any">Any</option>\r
-            <option value="Yes">Yes</option>\r
-            <option value="No">No</option>\r
-        </select>\r
-        <select ng-model="$parent.bgChangesFilterKeyword">\r
-            <option value="Any" disabled selected>BG Changes</option>\r
-            <option value="Any">Any</option>\r
-            <option value="Yes">Yes</option>\r
-            <option value="No">No</option>\r
-        </select>\r
-        <select ng-model="$parent.bpmChangesFilterKeyword">\r
-            <option value="Any" disabled selected>BPM Changes</option>\r
-            <option value="Any">Any</option>\r
-            <option value="Yes">Yes</option>\r
-            <option value="No">No</option>\r
-        </select>\r
+    <div id="filters-wrapper">\r
+        <div id="text-filters">\r
+            <input type="text" ng-model="$parent.packTitleFilterKeyword" placeholder="Pack Title" typeahead="pack.title for pack in packList | filter:$viewValue | limitTo:8"/>\r
+            <input type="text" ng-model="$parent.artistFilterKeyword" placeholder="Song Artist" typeahead="artist for artist in allSongArtists | filter:$viewValue | limitTo:8" />\r
+            <input type="text" ng-model="$parent.songTitleFilterKeyword" placeholder="Song Title" typeahead="song for song in allSongTitles | filter:$viewValue | limitTo:8" />\r
+            <input type="text" ng-model="$parent.stepArtistFilterKeyword" placeholder="Step Artist" typeahead="contributor for contributor in allContributors | filter:$viewValue | limitTo:8" />\r
+            <input type="text" ng-model="$parent.ratingFilterKeyword" placeholder="Block Rating"/>\r
+        </div>\r
+        <div id="select-filters">\r
+            <select ng-model="$parent.modeFilterKeyword">\r
+                <option value="Any" disabled selected>Mode</option>\r
+                <option value="Any">Any</option>\r
+                <option value="single">Single</option>\r
+                <option value="double">Double</option>\r
+            </select>\r
+            <select ng-model="$parent.difficultyFilterKeyword">\r
+                <option value="Any" disabled selected>Difficulty</option>\r
+                <option value="Any">Any</option>\r
+                <option value="Novice">Novice</option>\r
+                <option value="Easy">Easy</option>\r
+                <option value="Medium">Medium</option>\r
+                <option value="Hard">Hard</option>\r
+                <option value="Expert">Expert</option>\r
+                <option value="Edit">Edit</option>\r
+            </select>\r
+            <select ng-model="$parent.fgChangesFilterKeyword">\r
+                <option value="Any" disabled selected>FG Changes</option>\r
+                <option value="Any">Any</option>\r
+                <option value="Yes">Yes</option>\r
+                <option value="No">No</option>\r
+            </select>\r
+            <select ng-model="$parent.bgChangesFilterKeyword">\r
+                <option value="Any" disabled selected>BG Changes</option>\r
+                <option value="Any">Any</option>\r
+                <option value="Yes">Yes</option>\r
+                <option value="No">No</option>\r
+            </select>\r
+            <select ng-model="$parent.bpmChangesFilterKeyword">\r
+                <option value="Any" disabled selected>BPM Changes</option>\r
+                <option value="Any">Any</option>\r
+                <option value="Yes">Yes</option>\r
+                <option value="No">No</option>\r
+            </select>\r
+        </div>\r
+        <div id="sorts">\r
+            <select ng-model="$parent.sortOrder">\r
+                <option value="alpha" selected>Alphabetical</option>\r
+                <option value="chrono">Newest</option>\r
+            </select><br />\r
+            <label>Reverse sort: \r
+                <input type="checkbox" ng-model="$parent.reverseSort">\r
+            </label>\r
+        </div>\r
     </div>\r
 </div>\r
 \r
index f16ce23..e39c742 100644 (file)
@@ -19,8 +19,10 @@ angular.module("DivinElegy.pages.packs", ["DivinElegy.components.simfiles","Divi
     $scope.allContributors = [];
     $scope.allSongTitles = [];
     $scope.allSongArtists = [];
+    $scope.sortOrder = "alpha";
+    $scope.reverseSort = false;
     
-    var watchMen = ['packTitleFilterKeyword', 'artistFilterKeyword', 'songTitleFilterKeyword', 'difficultyFilterKeyword', 'ratingFilterKeyword', 'stepArtistFilterKeyword', 'fgChangesFilterKeyword', 'bgChangesFilterKeyword', 'bpmChangesFilterKeyword', 'modeFilterKeyword'];
+    var watchMen = ['packTitleFilterKeyword', 'artistFilterKeyword', 'songTitleFilterKeyword', 'difficultyFilterKeyword', 'ratingFilterKeyword', 'stepArtistFilterKeyword', 'fgChangesFilterKeyword', 'bgChangesFilterKeyword', 'bpmChangesFilterKeyword', 'modeFilterKeyword', 'sortOrder', 'reverseSort'];
     $scope.$watchGroup(watchMen, function(newValues, oldValues) {
         applyFilters();
     });
@@ -126,7 +128,42 @@ angular.module("DivinElegy.pages.packs", ["DivinElegy.components.simfiles","Divi
     
     var applyFilters = function()
     {
-        $scope.filteredPackList = filterFilter(filterFilter($scope.packList, packTitleFilter), simfileFilter);
+        $scope.filteredPackList = filterFilter(filterFilter($scope.packList, packTitleFilter), simfileFilter).sort(getSortFunction($scope.sortOrder, $scope.reverseSort));
+    };
+    
+    var getSortFunction = function(order, reverse)
+    {
+        reverse = reverse ? -1 : 1;
+        switch (order)
+        {
+            // Simple alpha numeric sort. 
+            case "alpha":
+                return function (packA, packB) 
+                {
+                    var a = packA.title.toLowerCase();
+                    var b = packB.title.toLowerCase();
+                    if (a === b)
+                        return 0; 
+                    
+                    if (typeof a === typeof b)
+                        return a < b ? -1*reverse : 1*reverse; 
+                    
+                    return typeof a < typeof b ? -1*reverse : 1*reverse;
+                }
+                
+            case "chrono":
+                return function(packA, packB)
+                {
+                    //XXX: lol i'm sorry
+                    var dateA = Date.parse(packA.uploaded.replace(/th|st|nd|rd/g, ''));
+                    var dateB = Date.parse(packB.uploaded.replace(/th|st|nd|rd/g, ''));
+                    
+                    if(dateA === dateB)
+                        return 0
+                    
+                    return dateA > dateB ? -1*reverse : 1*reverse;
+                };
+        }
     };
 
     SimfileService.getPacks().then(function(packs)
@@ -150,7 +187,7 @@ angular.module("DivinElegy.pages.packs", ["DivinElegy.components.simfiles","Divi
             $scope.pageSize = UiSettingsService.getDirective('simfilesPerPageAuto') ? Math.floor(($window.innerHeight - 280)/40 - 1) : UiSettingsService.getDirective('simfilesPerPage');
             $scope.currentPage = 1;
             $scope.packList = packs;
-            $scope.filteredPackList = packs;
+            $scope.filteredPackList = packs.sort(getSortFunction($scope.sortOrder, $scope.reverseSort));
             
             for(var i =0; i<packs.length; i++)
             {