summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Thompson <dthompson2@worcester.edu>2014-10-15 22:36:58 -0400
committerDavid Thompson <dthompson2@worcester.edu>2014-10-15 22:36:58 -0400
commit43dc1e9dcc762be0f0e24c80f862f8425b093133 (patch)
tree4fe2171b55d607c3b33016440cb11dd03b26682a
parentc45bbaf0c3aaf91150088d5153bfaa86c092fdf7 (diff)
js: Add loading spinner to packages page.
* css/guix.css: Add spinner styles. * js/controller/packages.js (guix.packages.view): Explicitly redraw after loading packages. * js/model/packages.js (guix.packages.Packages): Load packages in the background. * js/view/layout.js (guix.withLayout): Cast elem to array if needed. * js/view/packages.js (guix.packages.view): Render spinner when there are no packages to display.
-rw-r--r--css/guix.css104
-rw-r--r--js/controller/packages.js11
-rw-r--r--js/model/packages.js6
-rw-r--r--js/view/layout.js4
-rw-r--r--js/view/packages.js8
5 files changed, 124 insertions, 9 deletions
diff --git a/css/guix.css b/css/guix.css
index 0534209..040f239 100644
--- a/css/guix.css
+++ b/css/guix.css
@@ -13,3 +13,107 @@
.sorter {
cursor: pointer;
}
+
+/* Loading Spinner */
+
+@-webkit-keyframes spinner {
+ 0% {
+ -webkit-transform: rotate(0deg);
+ -moz-transform: rotate(0deg);
+ -ms-transform: rotate(0deg);
+ -o-transform: rotate(0deg);
+ transform: rotate(0deg);
+ }
+
+ 100% {
+ -webkit-transform: rotate(360deg);
+ -moz-transform: rotate(360deg);
+ -ms-transform: rotate(360deg);
+ -o-transform: rotate(360deg);
+ transform: rotate(360deg);
+ }
+}
+
+@-moz-keyframes spinner {
+ 0% {
+ -webkit-transform: rotate(0deg);
+ -moz-transform: rotate(0deg);
+ -ms-transform: rotate(0deg);
+ -o-transform: rotate(0deg);
+ transform: rotate(0deg);
+ }
+
+ 100% {
+ -webkit-transform: rotate(360deg);
+ -moz-transform: rotate(360deg);
+ -ms-transform: rotate(360deg);
+ -o-transform: rotate(360deg);
+ transform: rotate(360deg);
+ }
+}
+
+@-o-keyframes spinner {
+ 0% {
+ -webkit-transform: rotate(0deg);
+ -moz-transform: rotate(0deg);
+ -ms-transform: rotate(0deg);
+ -o-transform: rotate(0deg);
+ transform: rotate(0deg);
+ }
+
+ 100% {
+ -webkit-transform: rotate(360deg);
+ -moz-transform: rotate(360deg);
+ -ms-transform: rotate(360deg);
+ -o-transform: rotate(360deg);
+ transform: rotate(360deg);
+ }
+}
+
+@keyframes spinner {
+ 0% {
+ -webkit-transform: rotate(0deg);
+ -moz-transform: rotate(0deg);
+ -ms-transform: rotate(0deg);
+ -o-transform: rotate(0deg);
+ transform: rotate(0deg);
+ }
+
+ 100% {
+ -webkit-transform: rotate(360deg);
+ -moz-transform: rotate(360deg);
+ -ms-transform: rotate(360deg);
+ -o-transform: rotate(360deg);
+ transform: rotate(360deg);
+ }
+}
+
+/* :not(:required) hides this rule from IE9 and below */
+.spinner:not(:required) {
+ -webkit-animation: spinner 1500ms infinite linear;
+ -moz-animation: spinner 1500ms infinite linear;
+ -ms-animation: spinner 1500ms infinite linear;
+ -o-animation: spinner 1500ms infinite linear;
+ animation: spinner 1500ms infinite linear;
+ -webkit-border-radius: 0.5em;
+ -moz-border-radius: 0.5em;
+ -ms-border-radius: 0.5em;
+ -o-border-radius: 0.5em;
+ border-radius: 0.5em;
+ -webkit-box-shadow: rgba(0, 0, 51, 0.3) 1.5em 0 0 0, rgba(0, 0, 51, 0.3) 1.1em 1.1em 0 0, rgba(0, 0, 51, 0.3) 0 1.5em 0 0, rgba(0, 0, 51, 0.3) -1.1em 1.1em 0 0, rgba(0, 0, 51, 0.3) -1.5em 0 0 0, rgba(0, 0, 51, 0.3) -1.1em -1.1em 0 0, rgba(0, 0, 51, 0.3) 0 -1.5em 0 0, rgba(0, 0, 51, 0.3) 1.1em -1.1em 0 0;
+ -moz-box-shadow: rgba(0, 0, 51, 0.3) 1.5em 0 0 0, rgba(0, 0, 51, 0.3) 1.1em 1.1em 0 0, rgba(0, 0, 51, 0.3) 0 1.5em 0 0, rgba(0, 0, 51, 0.3) -1.1em 1.1em 0 0, rgba(0, 0, 51, 0.3) -1.5em 0 0 0, rgba(0, 0, 51, 0.3) -1.1em -1.1em 0 0, rgba(0, 0, 51, 0.3) 0 -1.5em 0 0, rgba(0, 0, 51, 0.3) 1.1em -1.1em 0 0;
+ box-shadow: rgba(0, 0, 51, 0.3) 1.5em 0 0 0, rgba(0, 0, 51, 0.3) 1.1em 1.1em 0 0, rgba(0, 0, 51, 0.3) 0 1.5em 0 0, rgba(0, 0, 51, 0.3) -1.1em 1.1em 0 0, rgba(0, 0, 51, 0.3) -1.5em 0 0 0, rgba(0, 0, 51, 0.3) -1.1em -1.1em 0 0, rgba(0, 0, 51, 0.3) 0 -1.5em 0 0, rgba(0, 0, 51, 0.3) 1.1em -1.1em 0 0;
+ display: inline-block;
+ font-size: 18px;
+ width: 1em;
+ height: 1em;
+ margin: 1.5em;
+ overflow: hidden;
+ text-indent: 100%;
+}
+
+.spinner-container {
+ width: 1em;
+ margin: 0 auto;
+ padding: 32px;
+}
diff --git a/js/controller/packages.js b/js/controller/packages.js
index 3a7858d..db94d72 100644
--- a/js/controller/packages.js
+++ b/js/controller/packages.js
@@ -20,7 +20,6 @@
function controller() {
var self = this;
- this.packages = packages.Packages();
this.pages = m.prop([]);
this.currentPageIndex = 0;
this.pageSize = 20;
@@ -47,10 +46,12 @@
this.phase = m.prop(packages.PHASE_NONE);
this.selectedPackage = m.prop(null);
- // All packages are visible initially
- this.packages.then(function(packages) {
- self.pages(self.paginate(packages, self.pageSize));
- });
+ this.packages = packages.Packages()
+ .then(function(packages) {
+ // All packages are visible initially
+ self.pages(self.paginate(packages, self.pageSize));
+ })
+ .then(m.redraw);
};
diff --git a/js/model/packages.js b/js/model/packages.js
index 5ea76a4..652d11a 100644
--- a/js/model/packages.js
+++ b/js/model/packages.js
@@ -19,7 +19,11 @@ guix.packages = {};
(function(packages) {
packages.Packages = function() {
- return m.request({ method: "GET", url: "packages.json" });
+ return m.request({
+ method: "GET",
+ url: "packages.json",
+ background: true
+ });
};
packages.Sorter = (function() {
diff --git a/js/view/layout.js b/js/view/layout.js
index 1ff641a..aa7834b 100644
--- a/js/view/layout.js
+++ b/js/view/layout.js
@@ -42,6 +42,10 @@ guix.withLayout = (function() {
]));
return function(elem) {
+ if(!_.isArray(elem)) {
+ elem = [elem];
+ }
+
return [
m("nav.navbar.navbar-default.navbar-static-top", {
role: "navigation"
diff --git a/js/view/packages.js b/js/view/packages.js
index e356984..e202471 100644
--- a/js/view/packages.js
+++ b/js/view/packages.js
@@ -16,6 +16,8 @@
// <http://www.gnu.org/licenses/>.
(function(packages) {
+ var spinner = m(".spinner-container", m(".spinner"));
+
packages.view = function(ctrl) {
function renderName(package) {
var name = package.name;
@@ -95,7 +97,7 @@
}, m("a", { href: "#" }, text));
}
- return m("ul.pagination", [
+ return m("div", m("ul.pagination", [
// Back page
renderPage("«", {
class: ctrl.isFirstPage() ? "disabled" : "",
@@ -125,7 +127,7 @@
return false;
}
})
- ]));
+ ])));
}
function renderSearchBox() {
@@ -237,7 +239,7 @@
return null;
}
- return guix.withLayout([
+ return guix.withLayout(_.isEmpty(ctrl.pages()) ? spinner : [
m("h2", [
"Packages",
m("span.badge", ctrl.packageCount())