diff --git a/ghost/admin/app/components/gh-download-count.js b/ghost/admin/app/components/gh-download-count.js new file mode 100644 index 0000000000..089c4d5329 --- /dev/null +++ b/ghost/admin/app/components/gh-download-count.js @@ -0,0 +1,41 @@ +import Ember from 'ember'; +import Component from 'ember-component'; +import injectService from 'ember-service/inject'; +import {task, timeout} from 'ember-concurrency'; + +const {testing} = Ember; +const INTERVAL = testing ? 20 : 2000; + +export default Component.extend({ + ajax: injectService(), + ghostPaths: injectService(), + + count: '', + + _poll: task(function* () { + let url = this.get('ghostPaths.count'); + let pattern = /(-?\d+)(\d{3})/; + + try { + let data = yield this.get('ajax').request(url); + let count = data.count.toString(); + + while (pattern.test(count)) { + count = count.replace(pattern, '$1,$2'); + } + + this.set('count', count); + + if (!testing) { + yield timeout(INTERVAL); + this.get('_poll').perform(); + } + } catch (e) { + // no-op - we don't want to create noise for a failed download count + } + }), + + didInsertElement() { + this.get('_poll').perform(); + } +}); diff --git a/ghost/admin/app/routes/setup/one.js b/ghost/admin/app/routes/setup/one.js deleted file mode 100644 index 8f6a1a5d30..0000000000 --- a/ghost/admin/app/routes/setup/one.js +++ /dev/null @@ -1,68 +0,0 @@ -import Ember from 'ember'; -import Route from 'ember-route'; -import injectService from 'ember-service/inject'; -import EmberObject from 'ember-object'; -import run from 'ember-runloop'; - -import AjaxService from 'ember-ajax/services/ajax'; - -// ember-cli-shims doesn't export Ember.testing -const {testing} = Ember; - -let DownloadCountPoller = EmberObject.extend({ - url: null, - count: '', - runId: null, - - ajax: AjaxService.create(), - notifications: injectService(), - - init() { - this._super(...arguments); - this.downloadCounter(); - this.poll(); - }, - - poll() { - let interval = testing ? 20 : 2000; - let runId = run.later(this, function () { - this.downloadCounter(); - if (!testing) { - this.poll(); - } - }, interval); - - this.set('runId', runId); - }, - - downloadCounter() { - this.get('ajax').request(this.get('url')).then((data) => { - let pattern = /(-?\d+)(\d{3})/; - let count = data.count.toString(); - - while (pattern.test(count)) { - count = count.replace(pattern, '$1,$2'); - } - - this.set('count', count); - }).catch((error) => { - this.set('count', ''); - this.get('notifications').showAPIError(error); - }); - } -}); - -export default Route.extend({ - ghostPaths: injectService(), - - model() { - return DownloadCountPoller.create({url: this.get('ghostPaths.count')}); - }, - - resetController(controller, isExiting) { - if (isExiting) { - run.cancel(controller.get('model.runId')); - controller.set('model', null); - } - } -}); diff --git a/ghost/admin/app/templates/components/gh-download-count.hbs b/ghost/admin/app/templates/components/gh-download-count.hbs new file mode 100644 index 0000000000..544a138fde --- /dev/null +++ b/ghost/admin/app/templates/components/gh-download-count.hbs @@ -0,0 +1,5 @@ +{{#if hasBlock}} + {{yield count}} +{{else}} + {{count}} +{{/if}} diff --git a/ghost/admin/app/templates/setup/one.hbs b/ghost/admin/app/templates/setup/one.hbs index 7d096c4efd..57c761e140 100644 --- a/ghost/admin/app/templates/setup/one.hbs +++ b/ghost/admin/app/templates/setup/one.hbs @@ -1,6 +1,6 @@

Welcome to Ghost!

-

All over the world, people have started {{model.count}} incredible blogs with Ghost. Today, we’re starting yours.

+

All over the world, people have started {{gh-download-count}} incredible blogs with Ghost. Today, we’re starting yours.

diff --git a/ghost/admin/tests/acceptance/setup-test.js b/ghost/admin/tests/acceptance/setup-test.js index 727e6ce6cf..93e6a0d457 100644 --- a/ghost/admin/tests/acceptance/setup-test.js +++ b/ghost/admin/tests/acceptance/setup-test.js @@ -100,9 +100,8 @@ describe('Acceptance: Setup', function () { .to.be.false; // it displays download count (count increments for each ajax call - // and polling is disabled in testing so our count should be "2" - - // 1 for first load and 1 for first poll) - expect(find('.gh-flow-content em').text()).to.equal('2'); + // and polling is disabled in testing so our count should be "1" + expect(find('.gh-flow-content em').text().trim()).to.equal('1'); }); click('.gh-btn-green'); diff --git a/ghost/admin/tests/integration/components/gh-download-count-test.js b/ghost/admin/tests/integration/components/gh-download-count-test.js new file mode 100644 index 0000000000..e026e236e3 --- /dev/null +++ b/ghost/admin/tests/integration/components/gh-download-count-test.js @@ -0,0 +1,45 @@ +import {expect} from 'chai'; +import {describe, it} from 'mocha'; +import {setupComponentTest} from 'ember-mocha'; +import hbs from 'htmlbars-inline-precompile'; +import Pretender from 'pretender'; +import wait from 'ember-test-helpers/wait'; + +describe('Integration: Component: gh-download-count', function() { + setupComponentTest('gh-download-count', { + integration: true + }); + + let server; + + beforeEach(function () { + server = new Pretender(); + server.get('https://count.ghost.org/', function () { + return [200, {}, JSON.stringify({count: 42})]; + }); + }); + + afterEach(function () { + server.shutdown(); + }); + + it('hits count endpoint and renders', function () { + this.render(hbs`{{gh-download-count}}`); + + return wait().then(() => { + expect(this.$().text().trim()).to.equal('42'); + }); + }); + + it('renders with a block', function () { + this.render(hbs` + {{#gh-download-count as |count|}} + {{count}} downloads + {{/gh-download-count}} + `); + + return wait().then(() => { + expect(this.$().text().trim()).to.equal('42 downloads'); + }); + }); +});