diff --git a/app/components/category-list.hbs b/app/components/category-list.hbs
deleted file mode 100644
index ff338e747f5..00000000000
--- a/app/components/category-list.hbs
+++ /dev/null
@@ -1,10 +0,0 @@
-
- {{#each @categories as |category|}}
-
- {{/each}}
-
\ No newline at end of file
diff --git a/app/components/crate-list-name-only.hbs b/app/components/crate-list-name-only.hbs
deleted file mode 100644
index cf16b012c1a..00000000000
--- a/app/components/crate-list-name-only.hbs
+++ /dev/null
@@ -1,10 +0,0 @@
-
- {{#each @crates as |crate index|}}
-
- {{/each}}
-
\ No newline at end of file
diff --git a/app/components/crate-list-newest.hbs b/app/components/crate-list-newest.hbs
deleted file mode 100644
index d449880b2d8..00000000000
--- a/app/components/crate-list-newest.hbs
+++ /dev/null
@@ -1,11 +0,0 @@
-
- {{#each @crates as |crate index|}}
-
- {{/each}}
-
\ No newline at end of file
diff --git a/app/components/front-page-list.hbs b/app/components/front-page-list.hbs
deleted file mode 100644
index 34685dc9832..00000000000
--- a/app/components/front-page-list.hbs
+++ /dev/null
@@ -1,5 +0,0 @@
-{{#if @ordered}}
-
{{yield (component "front-page-list/item")}}
-{{else}}
- {{yield (component "front-page-list/item")}}
-{{/if}}
diff --git a/app/components/front-page-list.module.css b/app/components/front-page-list.module.css
deleted file mode 100644
index d594abb0773..00000000000
--- a/app/components/front-page-list.module.css
+++ /dev/null
@@ -1,5 +0,0 @@
-.list {
- list-style: none;
- padding: 0;
-}
-
diff --git a/app/components/front-page-list/item.hbs b/app/components/front-page-list/item.hbs
index 75aed5ba476..9742d95f843 100644
--- a/app/components/front-page-list/item.hbs
+++ b/app/components/front-page-list/item.hbs
@@ -1,9 +1,7 @@
-
-
-
-
{{@title}}
- {{#if @subtitle}}
{{@subtitle}}
{{/if}}
-
- {{svg-jar "chevron-right" local-class="right"}}
-
-
+
+
+
{{@title}}
+ {{#if @subtitle}}
{{@subtitle}}
{{/if}}
+
+ {{svg-jar "chevron-right" local-class="right"}}
+
\ No newline at end of file
diff --git a/app/components/front-page-list/item/placeholder.hbs b/app/components/front-page-list/item/placeholder.hbs
new file mode 100644
index 00000000000..67282422b8a
--- /dev/null
+++ b/app/components/front-page-list/item/placeholder.hbs
@@ -0,0 +1,7 @@
+
+
+
+ {{#if @withSubtitle}}
{{/if}}
+
+ {{svg-jar "chevron-right" local-class="right"}}
+
\ No newline at end of file
diff --git a/app/components/front-page-list/item/placeholder.module.css b/app/components/front-page-list/item/placeholder.module.css
new file mode 100644
index 00000000000..b15bb7c54b7
--- /dev/null
+++ b/app/components/front-page-list/item/placeholder.module.css
@@ -0,0 +1,39 @@
+.link {
+ display: flex;
+ align-items: center;
+ width: 100%;
+ min-height: 60px;
+ margin: 8px 0;
+ padding: 0 10px;
+ background-color: var(--main-bg-dark);
+}
+
+.left {
+ flex-grow: 1;
+ width: 0;
+}
+
+.title {
+ height: 16px;
+ width: 150px;
+ border-radius: 8px;
+ background: rgb(118, 131, 138);
+ opacity: 0.25;
+}
+
+.subtitle {
+ height: 13px;
+ width: 90px;
+ margin-top: 4px;
+ border-radius: 6.5px;
+ background: rgb(118, 131, 138);
+ opacity: 0.2;
+}
+
+.right {
+ flex-shrink: 0;
+ height: 16px;
+ width: auto;
+ margin-left: 10px;
+ color: rgb(118, 131, 138);
+}
diff --git a/app/components/keyword-list.hbs b/app/components/keyword-list.hbs
deleted file mode 100644
index e70e061cbd2..00000000000
--- a/app/components/keyword-list.hbs
+++ /dev/null
@@ -1,10 +0,0 @@
-
- {{#each @keywords as |keyword|}}
-
- {{/each}}
-
\ No newline at end of file
diff --git a/app/controllers/index.js b/app/controllers/index.js
index 6b5263cde0c..010da8db696 100644
--- a/app/controllers/index.js
+++ b/app/controllers/index.js
@@ -1,5 +1,33 @@
import Controller from '@ember/controller';
+import { computed } from '@ember/object';
+import { readOnly } from '@ember/object/computed';
+import { inject as service } from '@ember/service';
+
+import { task } from 'ember-concurrency';
export default Controller.extend({
- hasData: true,
+ fetcher: service(),
+
+ model: readOnly('dataTask.lastSuccessful.value'),
+
+ hasData: computed('dataTask.{lastSuccessful,isRunning}', function () {
+ return this.get('dataTask.lastSuccessful') || !this.get('dataTask.isRunning');
+ }),
+
+ dataTask: task(function* () {
+ let data = yield this.fetcher.ajax('/api/v1/summary');
+
+ addCrates(this.store, data.new_crates);
+ addCrates(this.store, data.most_downloaded);
+ addCrates(this.store, data.just_updated);
+ addCrates(this.store, data.most_recently_downloaded);
+
+ return data;
+ }).drop(),
});
+
+function addCrates(store, crates) {
+ for (let i = 0; i < crates.length; i++) {
+ crates[i] = store.push(store.normalize('crate', crates[i]));
+ }
+}
diff --git a/app/helpers/placeholders.js b/app/helpers/placeholders.js
new file mode 100644
index 00000000000..0fecb6d32e6
--- /dev/null
+++ b/app/helpers/placeholders.js
@@ -0,0 +1,3 @@
+import { helper } from '@ember/component/helper';
+
+export default helper(([count]) => new Array(count));
diff --git a/app/routes/index.js b/app/routes/index.js
index 226dd33e6f2..b6acba49184 100644
--- a/app/routes/index.js
+++ b/app/routes/index.js
@@ -2,7 +2,7 @@ import Route from '@ember/routing/route';
import { inject as service } from '@ember/service';
export default Route.extend({
- fetcher: service(),
+ fastboot: service(),
headTags() {
return [
@@ -16,26 +16,12 @@ export default Route.extend({
];
},
- setupController(controller, model) {
- this._super(controller, model);
+ setupController(controller) {
this.controllerFor('application').set('searchQuery', null);
- },
-
- model() {
- return this.fetcher.ajax('/api/v1/summary');
- },
- // eslint-disable-next-line no-unused-vars
- afterModel(model, transition) {
- addCrates(this.store, model.new_crates);
- addCrates(this.store, model.most_downloaded);
- addCrates(this.store, model.just_updated);
- addCrates(this.store, model.most_recently_downloaded);
+ let promise = controller.dataTask.perform();
+ if (this.fastboot.isFastBoot) {
+ this.fastboot.deferRendering(promise);
+ }
},
});
-
-function addCrates(store, crates) {
- for (let i = 0; i < crates.length; i++) {
- crates[i] = store.push(store.normalize('crate', crates[i]));
- }
-}
diff --git a/app/styles/index.module.css b/app/styles/index.module.css
index 5818c8972dd..ae47ce051bb 100644
--- a/app/styles/index.module.css
+++ b/app/styles/index.module.css
@@ -86,13 +86,9 @@
font-size: 105%;
line-height: 20px;
}
-
- > section[aria-busy="true"] > h2::after {
- content: '';
- background-image: url('/assets/ajax-loader.gif');
- display: inline-block;
- height: 16px;
- width: 16px;
- }
}
+.list {
+ list-style: none;
+ padding: 0;
+}
diff --git a/app/templates/index.hbs b/app/templates/index.hbs
index 569aa424e09..5f2782195ef 100644
--- a/app/templates/index.hbs
+++ b/app/templates/index.hbs
@@ -36,28 +36,149 @@
-
+
New Crates
-
+
+ {{#if this.dataTask.isRunning}}
+ {{#each (placeholders 10)}}
+ -
+
+
+ {{/each}}
+ {{else}}
+ {{#each this.model.new_crates as |crate index|}}
+ -
+
+
+ {{/each}}
+ {{/if}}
+
-
+
+
Most Downloaded
-
+
+ {{#if this.dataTask.isRunning}}
+ {{#each (placeholders 10)}}
+ -
+
+
+ {{/each}}
+ {{else}}
+ {{#each this.model.most_downloaded as |crate index|}}
+ -
+
+
+ {{/each}}
+ {{/if}}
+
-
+
+
Just Updated
-
+
+ {{#if this.dataTask.isRunning}}
+ {{#each (placeholders 10)}}
+ -
+
+
+ {{/each}}
+ {{else}}
+ {{#each this.model.just_updated as |crate index|}}
+ -
+
+
+ {{/each}}
+ {{/if}}
+
-
+
+
Most Recent Downloads
-
+
+ {{#if this.dataTask.isRunning}}
+ {{#each (placeholders 10)}}
+ -
+
+
+ {{/each}}
+ {{else}}
+ {{#each this.model.most_recently_downloaded as |crate index|}}
+ -
+
+
+ {{/each}}
+ {{/if}}
+
-
+
+
Popular Keywords (see all)
-
+
+ {{#if this.dataTask.isRunning}}
+ {{#each (placeholders 10)}}
+ -
+
+
+ {{/each}}
+ {{else}}
+ {{#each this.model.popular_keywords as |keyword|}}
+ -
+
+
+ {{/each}}
+ {{/if}}
+
-
+
+
Popular Categories (see all)
-
+
+ {{#if this.dataTask.isRunning}}
+ {{#each (placeholders 10)}}
+ -
+
+
+ {{/each}}
+ {{else}}
+ {{#each this.model.popular_categories as |category|}}
+ -
+
+
+ {{/each}}
+ {{/if}}
+