From 4f02499d36c762eaa0ff9281c3d36036580a0a15 Mon Sep 17 00:00:00 2001 From: Kit La Touche Date: Sun, 28 Aug 2016 01:16:54 -0600 Subject: [PATCH 01/14] [WIP] Show user details. The intent is to eventually be able to go to a user's profile page and see a list of their crates. See #409. --- app/router.js | 1 + app/routes/user.js | 12 ++++++++++++ app/templates/user.hbs | 19 +++++++++++++++++++ src/lib.rs | 1 + src/user/mod.rs | 15 +++++++++++++++ tests/unit/routes/user-test.js | 11 +++++++++++ 6 files changed, 59 insertions(+) create mode 100644 app/routes/user.js create mode 100644 app/templates/user.hbs create mode 100644 tests/unit/routes/user-test.js diff --git a/app/router.js b/app/router.js index d858f0d5c9a..8e48c6c8ca7 100644 --- a/app/router.js +++ b/app/router.js @@ -27,6 +27,7 @@ Router.map(function() { this.route('crates'); this.route('following'); }); + this.route('user', { path: '/users/:user_id' }); this.route('install'); this.route('search'); this.route('dashboard'); diff --git a/app/routes/user.js b/app/routes/user.js new file mode 100644 index 00000000000..3a702ed09ba --- /dev/null +++ b/app/routes/user.js @@ -0,0 +1,12 @@ +import Ember from 'ember'; + +export default Ember.Route.extend({ + model(params) { + return this.store.find('user', params.user_id).catch(e => { + if (e.errors.any(e => e.detail === 'Not Found')) { + this.controllerFor('application').set('nextFlashError', `User '${params.user_id}' does not exist`); + return this.replaceWith('index'); + } + }); + }, +}); diff --git a/app/templates/user.hbs b/app/templates/user.hbs new file mode 100644 index 00000000000..dcc7506f170 --- /dev/null +++ b/app/templates/user.hbs @@ -0,0 +1,19 @@ +
+ +

{{ model.login }}

+
+ +
+

{{ model.login }}

+ +
+ {{#user-link user=model }} {{user-avatar user=model size='medium'}} {{/user-link}} + +
+
Name
+
{{ model.name }}
+
GitHub Account
+
{{ model.login }}
+
+
+
diff --git a/src/lib.rs b/src/lib.rs index 3d01759d200..33596374d86 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -100,6 +100,7 @@ pub fn middleware(app: Arc) -> MiddlewareBuilder { api_router.get("/versions/:version_id", C(version::show)); api_router.get("/keywords", C(keyword::index)); api_router.get("/keywords/:keyword_id", C(keyword::show)); + api_router.get("/users/:user_id", C(user::show)); let api_router = Arc::new(R404(api_router)); let mut router = RouteBuilder::new(); diff --git a/src/user/mod.rs b/src/user/mod.rs index 3d7a2a68f7f..904e1a09049 100644 --- a/src/user/mod.rs +++ b/src/user/mod.rs @@ -2,6 +2,7 @@ use std::collections::HashMap; use conduit::{Request, Response}; use conduit_cookie::{RequestSession}; +use conduit_router::RequestParams; use pg::GenericConnection; use pg::rows::Row; use pg::types::Slice; @@ -288,6 +289,20 @@ pub fn me(req: &mut Request) -> CargoResult { Ok(req.json(&R{ user: user.clone().encodable(), api_token: token })) } +/// Handles the `GET /users/:user_id` route. +pub fn show(req: &mut Request) -> CargoResult { + let name = &req.params()["user_id"]; + let conn = try!(req.tx()); + let user = try!(User::find_by_login(conn, &name)); + + #[derive(RustcEncodable)] + struct R { + user: EncodableUser, + } + Ok(req.json(&R{ user: user.clone().encodable() })) +} + + /// Handles the `GET /me/updates` route. pub fn updates(req: &mut Request) -> CargoResult { let user = try!(req.user()); diff --git a/tests/unit/routes/user-test.js b/tests/unit/routes/user-test.js new file mode 100644 index 00000000000..b63eea3e219 --- /dev/null +++ b/tests/unit/routes/user-test.js @@ -0,0 +1,11 @@ +import { moduleFor, test } from 'ember-qunit'; + +moduleFor('route:user', 'Unit | Route | user', { + // Specify the other units that are required for this test. + // needs: ['controller:foo'] +}); + +test('it exists', function(assert) { + let route = this.subject(); + assert.ok(route); +}); From 3f42fe8e441e6a711826691c99d96bae4d3f78ff Mon Sep 17 00:00:00 2001 From: Kit La Touche Date: Sun, 28 Aug 2016 12:22:07 -0600 Subject: [PATCH 02/14] Fix linting errors in user unit test. --- tests/unit/routes/user-test.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/unit/routes/user-test.js b/tests/unit/routes/user-test.js index b63eea3e219..9d432694366 100644 --- a/tests/unit/routes/user-test.js +++ b/tests/unit/routes/user-test.js @@ -1,11 +1,11 @@ import { moduleFor, test } from 'ember-qunit'; moduleFor('route:user', 'Unit | Route | user', { - // Specify the other units that are required for this test. - // needs: ['controller:foo'] + // Specify the other units that are required for this test. + // needs: ['controller:foo'] }); test('it exists', function(assert) { - let route = this.subject(); - assert.ok(route); + let route = this.subject(); + assert.ok(route); }); From 0b60db66633ab8992cb63f581ced72c289f6ad49 Mon Sep 17 00:00:00 2001 From: Kit La Touche Date: Sun, 28 Aug 2016 15:47:30 -0600 Subject: [PATCH 03/14] Improve per-user crate display. --- app/controllers/user.js | 23 +++++++++++++++++++++++ app/routes/user.js | 19 +++++++++++++++++++ app/templates/user.hbs | 25 +++++++++++++++---------- tests/unit/controllers/user-test.js | 12 ++++++++++++ 4 files changed, 69 insertions(+), 10 deletions(-) create mode 100644 app/controllers/user.js create mode 100644 tests/unit/controllers/user-test.js diff --git a/app/controllers/user.js b/app/controllers/user.js new file mode 100644 index 00000000000..bf7e43e51af --- /dev/null +++ b/app/controllers/user.js @@ -0,0 +1,23 @@ +import Ember from 'ember'; + +const TO_SHOW = 5; +const { computed } = Ember; + +export default Ember.Controller.extend({ + init() { + this._super(...arguments); + + this.fetchingFeed = true; + this.loadingMore = false; + this.hasMore = false; + this.crates = []; + }, + + visibleCrates: computed('crates', function() { + return this.get('crates').slice(0, TO_SHOW); + }), + + hasMoreCrates: computed('crates', function() { + return this.get('crates.length') > TO_SHOW; + }) +}); diff --git a/app/routes/user.js b/app/routes/user.js index 3a702ed09ba..fb0dfc37c84 100644 --- a/app/routes/user.js +++ b/app/routes/user.js @@ -1,6 +1,15 @@ import Ember from 'ember'; export default Ember.Route.extend({ + data: {}, + + setupController(controller, model) { + this._super(controller, model); + + controller.set('fetchingFeed', true); + controller.set('crates', this.get('data.crates')); + }, + model(params) { return this.store.find('user', params.user_id).catch(e => { if (e.errors.any(e => e.detail === 'Not Found')) { @@ -9,4 +18,14 @@ export default Ember.Route.extend({ } }); }, + + afterModel(user) { + let crates = this.store.query('crate', { + user_id: user.get('id') + }); + + return Ember.RSVP.hash({ + crates, + }).then((hash) => this.set('data', hash)); + } }); diff --git a/app/templates/user.hbs b/app/templates/user.hbs index dcc7506f170..85a90b40380 100644 --- a/app/templates/user.hbs +++ b/app/templates/user.hbs @@ -1,19 +1,24 @@
- + {{#user-link user=model }} {{user-avatar user=model size='medium'}} {{/user-link}}

{{ model.login }}

-

{{ model.login }}

-
- {{#user-link user=model }} {{user-avatar user=model size='medium'}} {{/user-link}} +
+
+

+ + Crates +

-
-
Name
-
{{ model.name }}
-
GitHub Account
-
{{ model.login }}
-
+ {{#if hasMoreCrates}} + + {{link-to 'Show all' 'me.crates'}} + + {{/if}} +
+ {{crate-downloads-list crates=visibleCrates}} +
diff --git a/tests/unit/controllers/user-test.js b/tests/unit/controllers/user-test.js new file mode 100644 index 00000000000..db02a101020 --- /dev/null +++ b/tests/unit/controllers/user-test.js @@ -0,0 +1,12 @@ +import { moduleFor, test } from 'ember-qunit'; + +moduleFor('controller:user', 'Unit | Controller | user', { + // Specify the other units that are required for this test. + // needs: ['controller:foo'] +}); + +// Replace this with your real tests. +test('it exists', function(assert) { + let controller = this.subject(); + assert.ok(controller); +}); From f23672c880ee52ce334c072a1a8f3617cc7c3695 Mon Sep 17 00:00:00 2001 From: Kit La Touche Date: Sun, 28 Aug 2016 16:37:34 -0600 Subject: [PATCH 04/14] Add long crate views for arbitrary users. --- app/controllers/user/crates.js | 18 +++++++ app/controllers/{user.js => user/index.js} | 0 app/router.js | 4 +- app/routes/user/crates.js | 23 +++++++++ app/routes/{user.js => user/index.js} | 0 app/templates/user/crates.hbs | 58 ++++++++++++++++++++++ app/templates/{user.hbs => user/index.hbs} | 0 tests/unit/controllers/user/crates-test.js | 12 +++++ tests/unit/routes/user/crates-test.js | 11 ++++ 9 files changed, 125 insertions(+), 1 deletion(-) create mode 100644 app/controllers/user/crates.js rename app/controllers/{user.js => user/index.js} (100%) create mode 100644 app/routes/user/crates.js rename app/routes/{user.js => user/index.js} (100%) create mode 100644 app/templates/user/crates.hbs rename app/templates/{user.hbs => user/index.hbs} (100%) create mode 100644 tests/unit/controllers/user/crates-test.js create mode 100644 tests/unit/routes/user/crates-test.js diff --git a/app/controllers/user/crates.js b/app/controllers/user/crates.js new file mode 100644 index 00000000000..e83045b5615 --- /dev/null +++ b/app/controllers/user/crates.js @@ -0,0 +1,18 @@ +import Ember from 'ember'; +import PaginationMixin from '../../mixins/pagination'; + +const { computed } = Ember; +// TODO: reduce duplicatoin with controllers/crates + +export default Ember.Controller.extend(PaginationMixin, { + queryParams: ['page', 'per_page', 'sort'], + page: '1', + per_page: 10, + sort: 'alpha', + + totalItems: computed.readOnly('model.crates.meta.total'), + + currentSortBy: computed('sort', function() { + return (this.get('sort') === 'downloads') ? 'Downloads' : 'Alphabetical'; + }), +}); diff --git a/app/controllers/user.js b/app/controllers/user/index.js similarity index 100% rename from app/controllers/user.js rename to app/controllers/user/index.js diff --git a/app/router.js b/app/router.js index 8e48c6c8ca7..bbd70ca54c8 100644 --- a/app/router.js +++ b/app/router.js @@ -27,7 +27,9 @@ Router.map(function() { this.route('crates'); this.route('following'); }); - this.route('user', { path: '/users/:user_id' }); + this.route('user', { path: '/users/:user_id' }, function() { + this.route('crates'); + }); this.route('install'); this.route('search'); this.route('dashboard'); diff --git a/app/routes/user/crates.js b/app/routes/user/crates.js new file mode 100644 index 00000000000..c5eb9871569 --- /dev/null +++ b/app/routes/user/crates.js @@ -0,0 +1,23 @@ +import Ember from 'ember'; +import AuthenticatedRoute from '../../mixins/authenticated-route'; + +export default Ember.Route.extend(AuthenticatedRoute, { + queryParams: { + page: { refreshModel: true }, + sort: { refreshModel: true }, + }, + + model(params) { + params.user_id = this.paramsFor("user").user_id; + return Ember.RSVP.hash({ + user: this.store.find('user', params.user_id), + crates: this.store.query('crate', params) + }).catch(e => { + if (e.errors.any(e => e.detail === 'Not Found')) { + this.controllerFor('application').set('nextFlashError', `User '${params.user_id}' does not exist`); + return this.replaceWith('index'); + } + }); + }, +}); + diff --git a/app/routes/user.js b/app/routes/user/index.js similarity index 100% rename from app/routes/user.js rename to app/routes/user/index.js diff --git a/app/templates/user/crates.hbs b/app/templates/user/crates.hbs new file mode 100644 index 00000000000..c4c14881876 --- /dev/null +++ b/app/templates/user/crates.hbs @@ -0,0 +1,58 @@ +
+ +

{{ model.user.login }}'s Crates

+
+ +{{! TODO: reduce duplication with templates/crates.hbs }} + +
+ + +
+ Sort by + {{#rl-dropdown-container class="dropdown-container"}} + {{#rl-dropdown-toggle tagName="a" class="dropdown"}} + + {{ currentSortBy }} + + {{/rl-dropdown-toggle}} + + {{#rl-dropdown tagName="ul" class="dropdown" closeOnChildClick="a:link"}} +
  • + {{#link-to (query-params sort="alpha")}} + Alphabetical + {{/link-to}} +
  • +
  • + {{#link-to (query-params sort="downloads")}} + Downloads + {{/link-to}} +
  • + {{/rl-dropdown}} + {{/rl-dropdown-container}} +
    +
    + +
    + {{#each model as |crate|}} + {{crate-row crate=crate}} + {{/each}} +
    + + diff --git a/app/templates/user.hbs b/app/templates/user/index.hbs similarity index 100% rename from app/templates/user.hbs rename to app/templates/user/index.hbs diff --git a/tests/unit/controllers/user/crates-test.js b/tests/unit/controllers/user/crates-test.js new file mode 100644 index 00000000000..a5ec0788309 --- /dev/null +++ b/tests/unit/controllers/user/crates-test.js @@ -0,0 +1,12 @@ +import { moduleFor, test } from 'ember-qunit'; + +moduleFor('controller:user/crates', 'Unit | Controller | user/crates', { + // Specify the other units that are required for this test. + // needs: ['controller:foo'] +}); + +// Replace this with your real tests. +test('it exists', function(assert) { + let controller = this.subject(); + assert.ok(controller); +}); diff --git a/tests/unit/routes/user/crates-test.js b/tests/unit/routes/user/crates-test.js new file mode 100644 index 00000000000..aae12693722 --- /dev/null +++ b/tests/unit/routes/user/crates-test.js @@ -0,0 +1,11 @@ +import { moduleFor, test } from 'ember-qunit'; + +moduleFor('route:user/crates', 'Unit | Route | user/crates', { + // Specify the other units that are required for this test. + // needs: ['controller:foo'] +}); + +test('it exists', function(assert) { + let route = this.subject(); + assert.ok(route); +}); From 320c4371427257332db0b76be8231f88822afbd9 Mon Sep 17 00:00:00 2001 From: Kit La Touche Date: Sun, 28 Aug 2016 17:19:32 -0600 Subject: [PATCH 05/14] Remove placeholder tests. --- tests/unit/controllers/user-test.js | 12 ------------ tests/unit/controllers/user/crates-test.js | 12 ------------ tests/unit/routes/user-test.js | 11 ----------- tests/unit/routes/user/crates-test.js | 11 ----------- 4 files changed, 46 deletions(-) delete mode 100644 tests/unit/controllers/user-test.js delete mode 100644 tests/unit/controllers/user/crates-test.js delete mode 100644 tests/unit/routes/user-test.js delete mode 100644 tests/unit/routes/user/crates-test.js diff --git a/tests/unit/controllers/user-test.js b/tests/unit/controllers/user-test.js deleted file mode 100644 index db02a101020..00000000000 --- a/tests/unit/controllers/user-test.js +++ /dev/null @@ -1,12 +0,0 @@ -import { moduleFor, test } from 'ember-qunit'; - -moduleFor('controller:user', 'Unit | Controller | user', { - // Specify the other units that are required for this test. - // needs: ['controller:foo'] -}); - -// Replace this with your real tests. -test('it exists', function(assert) { - let controller = this.subject(); - assert.ok(controller); -}); diff --git a/tests/unit/controllers/user/crates-test.js b/tests/unit/controllers/user/crates-test.js deleted file mode 100644 index a5ec0788309..00000000000 --- a/tests/unit/controllers/user/crates-test.js +++ /dev/null @@ -1,12 +0,0 @@ -import { moduleFor, test } from 'ember-qunit'; - -moduleFor('controller:user/crates', 'Unit | Controller | user/crates', { - // Specify the other units that are required for this test. - // needs: ['controller:foo'] -}); - -// Replace this with your real tests. -test('it exists', function(assert) { - let controller = this.subject(); - assert.ok(controller); -}); diff --git a/tests/unit/routes/user-test.js b/tests/unit/routes/user-test.js deleted file mode 100644 index 9d432694366..00000000000 --- a/tests/unit/routes/user-test.js +++ /dev/null @@ -1,11 +0,0 @@ -import { moduleFor, test } from 'ember-qunit'; - -moduleFor('route:user', 'Unit | Route | user', { - // Specify the other units that are required for this test. - // needs: ['controller:foo'] -}); - -test('it exists', function(assert) { - let route = this.subject(); - assert.ok(route); -}); diff --git a/tests/unit/routes/user/crates-test.js b/tests/unit/routes/user/crates-test.js deleted file mode 100644 index aae12693722..00000000000 --- a/tests/unit/routes/user/crates-test.js +++ /dev/null @@ -1,11 +0,0 @@ -import { moduleFor, test } from 'ember-qunit'; - -moduleFor('route:user/crates', 'Unit | Route | user/crates', { - // Specify the other units that are required for this test. - // needs: ['controller:foo'] -}); - -test('it exists', function(assert) { - let route = this.subject(); - assert.ok(route); -}); From 49a944aa962aa7bfc4f038276176c80e83e9e9e4 Mon Sep 17 00:00:00 2001 From: Kit La Touche Date: Sun, 28 Aug 2016 17:26:26 -0600 Subject: [PATCH 06/14] Fix linting errors. --- app/routes/user/crates.js | 2 +- app/routes/user/index.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/routes/user/crates.js b/app/routes/user/crates.js index c5eb9871569..630e9d02052 100644 --- a/app/routes/user/crates.js +++ b/app/routes/user/crates.js @@ -8,7 +8,7 @@ export default Ember.Route.extend(AuthenticatedRoute, { }, model(params) { - params.user_id = this.paramsFor("user").user_id; + params.user_id = this.paramsFor('user').user_id; return Ember.RSVP.hash({ user: this.store.find('user', params.user_id), crates: this.store.query('crate', params) diff --git a/app/routes/user/index.js b/app/routes/user/index.js index fb0dfc37c84..8b6a511083b 100644 --- a/app/routes/user/index.js +++ b/app/routes/user/index.js @@ -7,7 +7,7 @@ export default Ember.Route.extend({ this._super(controller, model); controller.set('fetchingFeed', true); - controller.set('crates', this.get('data.crates')); + controller.set('crates', this.get('data.crates')); }, model(params) { From 9f3709188d47c42ad1a29b68ce7c6ce6461bcdb7 Mon Sep 17 00:00:00 2001 From: Kit La Touche Date: Tue, 30 Aug 2016 14:50:55 -0600 Subject: [PATCH 07/14] Actually search crates by user_id, not username --- app/routes/user/crates.js | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/app/routes/user/crates.js b/app/routes/user/crates.js index 630e9d02052..c2acb2ae4db 100644 --- a/app/routes/user/crates.js +++ b/app/routes/user/crates.js @@ -8,16 +8,24 @@ export default Ember.Route.extend(AuthenticatedRoute, { }, model(params) { - params.user_id = this.paramsFor('user').user_id; - return Ember.RSVP.hash({ - user: this.store.find('user', params.user_id), - crates: this.store.query('crate', params) - }).catch(e => { - if (e.errors.any(e => e.detail === 'Not Found')) { - this.controllerFor('application').set('nextFlashError', `User '${params.user_id}' does not exist`); - return this.replaceWith('index'); + const user_id = this.paramsFor('user').user_id; + return this.store.find('user', user_id).then( + (user) => { + params.user_id = user.get('id'); + return Ember.RSVP.hash({ + crates: this.store.query('crate', params), + user + }); + }, + (e) => { + if (e.errors.any(e => e.detail === 'Not Found')) { + this + .controllerFor('application') + .set('nextFlashError', `User '${params.user_id}' does not exist`); + return this.replaceWith('index'); + } } - }); + ) }, }); From c790e336603c99d509ea2c4a722f837a4e8ec1f5 Mon Sep 17 00:00:00 2001 From: Kit La Touche Date: Tue, 30 Aug 2016 14:52:09 -0600 Subject: [PATCH 08/14] Remove auth-required on route. --- app/routes/user/crates.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/routes/user/crates.js b/app/routes/user/crates.js index c2acb2ae4db..0459b71861e 100644 --- a/app/routes/user/crates.js +++ b/app/routes/user/crates.js @@ -1,7 +1,6 @@ import Ember from 'ember'; -import AuthenticatedRoute from '../../mixins/authenticated-route'; -export default Ember.Route.extend(AuthenticatedRoute, { +export default Ember.Route.extend({ queryParams: { page: { refreshModel: true }, sort: { refreshModel: true }, From 4176b21c5f0a14c5327246e82f66298322826c9f Mon Sep 17 00:00:00 2001 From: Kit La Touche Date: Tue, 30 Aug 2016 17:06:45 -0600 Subject: [PATCH 09/14] Show crates properly on user profile pages --- app/controllers/{user/index.js => user.js} | 0 app/routes/{user/index.js => user.js} | 0 app/templates/user.hbs | 16 ++++++++++++ app/templates/user/crates.hbs | 7 +----- app/templates/user/index.hbs | 29 +++++----------------- 5 files changed, 23 insertions(+), 29 deletions(-) rename app/controllers/{user/index.js => user.js} (100%) rename app/routes/{user/index.js => user.js} (100%) create mode 100644 app/templates/user.hbs diff --git a/app/controllers/user/index.js b/app/controllers/user.js similarity index 100% rename from app/controllers/user/index.js rename to app/controllers/user.js diff --git a/app/routes/user/index.js b/app/routes/user.js similarity index 100% rename from app/routes/user/index.js rename to app/routes/user.js diff --git a/app/templates/user.hbs b/app/templates/user.hbs new file mode 100644 index 00000000000..6b6b170f22a --- /dev/null +++ b/app/templates/user.hbs @@ -0,0 +1,16 @@ +
    + {{#user-link user=model}} + {{user-avatar user=model size='medium'}} + {{/user-link}} +

    + {{#link-to 'user' model}} + {{ model.login }} + {{/link-to}} +

    +
    + +
    +
    + {{outlet}} +
    +
    diff --git a/app/templates/user/crates.hbs b/app/templates/user/crates.hbs index c4c14881876..3da7cdd9fb4 100644 --- a/app/templates/user/crates.hbs +++ b/app/templates/user/crates.hbs @@ -1,8 +1,3 @@ -
    - -

    {{ model.user.login }}'s Crates

    -
    - {{! TODO: reduce duplication with templates/crates.hbs }}
    @@ -40,7 +35,7 @@
    - {{#each model as |crate|}} + {{#each model.crates as |crate|}} {{crate-row crate=crate}} {{/each}}
    diff --git a/app/templates/user/index.hbs b/app/templates/user/index.hbs index 85a90b40380..6a95ec24514 100644 --- a/app/templates/user/index.hbs +++ b/app/templates/user/index.hbs @@ -1,24 +1,7 @@ -
    - {{#user-link user=model }} {{user-avatar user=model size='medium'}} {{/user-link}} -

    {{ model.login }}

    -
    +

    + Generic profile information here. +

    -
    -
    -
    -
    -

    - - Crates -

    - - {{#if hasMoreCrates}} - - {{link-to 'Show all' 'me.crates'}} - - {{/if}} -
    - {{crate-downloads-list crates=visibleCrates}} -
    -
    -
    +{{#link-to 'user.crates' model.login}} + See all their crates +{{/link-to}} From 1d9cbacba442e270192be1b37f4a6d66d3d8444d Mon Sep 17 00:00:00 2001 From: Kit La Touche Date: Tue, 30 Aug 2016 17:08:18 -0600 Subject: [PATCH 10/14] Fix linting problems --- app/routes/user/crates.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/routes/user/crates.js b/app/routes/user/crates.js index 0459b71861e..0f324a6f8d2 100644 --- a/app/routes/user/crates.js +++ b/app/routes/user/crates.js @@ -7,7 +7,7 @@ export default Ember.Route.extend({ }, model(params) { - const user_id = this.paramsFor('user').user_id; + const { user_id } = this.paramsFor('user'); return this.store.find('user', user_id).then( (user) => { params.user_id = user.get('id'); @@ -24,7 +24,7 @@ export default Ember.Route.extend({ return this.replaceWith('index'); } } - ) + ); }, }); From 135dcd69f9f00c62c658f370e794d6bc72745658 Mon Sep 17 00:00:00 2001 From: Kit La Touche Date: Thu, 1 Sep 2016 20:56:25 -0600 Subject: [PATCH 11/14] Collapse /users/:user_id and /users/:user_id/crates We don't need a distinct user profile page at the moment. --- app/controllers/user.js | 26 +++++++-------- app/controllers/user/crates.js | 18 ---------- app/router.js | 4 +-- app/routes/user.js | 36 +++++++++++--------- app/routes/user/crates.js | 30 ----------------- app/templates/user.hbs | 60 +++++++++++++++++++++++++++++++--- app/templates/user/crates.hbs | 53 ------------------------------ app/templates/user/index.hbs | 7 ---- 8 files changed, 89 insertions(+), 145 deletions(-) delete mode 100644 app/controllers/user/crates.js delete mode 100644 app/routes/user/crates.js delete mode 100644 app/templates/user/crates.hbs delete mode 100644 app/templates/user/index.hbs diff --git a/app/controllers/user.js b/app/controllers/user.js index bf7e43e51af..bfc99c8d576 100644 --- a/app/controllers/user.js +++ b/app/controllers/user.js @@ -1,23 +1,19 @@ import Ember from 'ember'; +import PaginationMixin from '../mixins/pagination'; -const TO_SHOW = 5; const { computed } = Ember; -export default Ember.Controller.extend({ - init() { - this._super(...arguments); +// TODO: reduce duplication with controllers/crates - this.fetchingFeed = true; - this.loadingMore = false; - this.hasMore = false; - this.crates = []; - }, +export default Ember.Controller.extend(PaginationMixin, { + queryParams: ['page', 'per_page', 'sort'], + page: '1', + per_page: 10, + sort: 'alpha', - visibleCrates: computed('crates', function() { - return this.get('crates').slice(0, TO_SHOW); - }), + totalItems: computed.readOnly('model.crates.meta.total'), - hasMoreCrates: computed('crates', function() { - return this.get('crates.length') > TO_SHOW; - }) + currentSortBy: computed('sort', function() { + return (this.get('sort') === 'downloads') ? 'Downloads' : 'Alphabetical'; + }), }); diff --git a/app/controllers/user/crates.js b/app/controllers/user/crates.js deleted file mode 100644 index e83045b5615..00000000000 --- a/app/controllers/user/crates.js +++ /dev/null @@ -1,18 +0,0 @@ -import Ember from 'ember'; -import PaginationMixin from '../../mixins/pagination'; - -const { computed } = Ember; -// TODO: reduce duplicatoin with controllers/crates - -export default Ember.Controller.extend(PaginationMixin, { - queryParams: ['page', 'per_page', 'sort'], - page: '1', - per_page: 10, - sort: 'alpha', - - totalItems: computed.readOnly('model.crates.meta.total'), - - currentSortBy: computed('sort', function() { - return (this.get('sort') === 'downloads') ? 'Downloads' : 'Alphabetical'; - }), -}); diff --git a/app/router.js b/app/router.js index bbd70ca54c8..8e48c6c8ca7 100644 --- a/app/router.js +++ b/app/router.js @@ -27,9 +27,7 @@ Router.map(function() { this.route('crates'); this.route('following'); }); - this.route('user', { path: '/users/:user_id' }, function() { - this.route('crates'); - }); + this.route('user', { path: '/users/:user_id' }); this.route('install'); this.route('search'); this.route('dashboard'); diff --git a/app/routes/user.js b/app/routes/user.js index 8b6a511083b..a8a0f79d850 100644 --- a/app/routes/user.js +++ b/app/routes/user.js @@ -1,6 +1,10 @@ import Ember from 'ember'; export default Ember.Route.extend({ + queryParams: { + page: { refreshModel: true }, + sort: { refreshModel: true }, + }, data: {}, setupController(controller, model) { @@ -11,21 +15,23 @@ export default Ember.Route.extend({ }, model(params) { - return this.store.find('user', params.user_id).catch(e => { - if (e.errors.any(e => e.detail === 'Not Found')) { - this.controllerFor('application').set('nextFlashError', `User '${params.user_id}' does not exist`); - return this.replaceWith('index'); + const { user_id } = params; + return this.store.find('user', user_id).then( + (user) => { + params.user_id = user.get('id'); + return Ember.RSVP.hash({ + crates: this.store.query('crate', params), + user + }); + }, + (e) => { + if (e.errors.any(e => e.detail === 'Not Found')) { + this + .controllerFor('application') + .set('nextFlashError', `User '${params.user_id}' does not exist`); + return this.replaceWith('index'); + } } - }); + ); }, - - afterModel(user) { - let crates = this.store.query('crate', { - user_id: user.get('id') - }); - - return Ember.RSVP.hash({ - crates, - }).then((hash) => this.set('data', hash)); - } }); diff --git a/app/routes/user/crates.js b/app/routes/user/crates.js deleted file mode 100644 index 0f324a6f8d2..00000000000 --- a/app/routes/user/crates.js +++ /dev/null @@ -1,30 +0,0 @@ -import Ember from 'ember'; - -export default Ember.Route.extend({ - queryParams: { - page: { refreshModel: true }, - sort: { refreshModel: true }, - }, - - model(params) { - const { user_id } = this.paramsFor('user'); - return this.store.find('user', user_id).then( - (user) => { - params.user_id = user.get('id'); - return Ember.RSVP.hash({ - crates: this.store.query('crate', params), - user - }); - }, - (e) => { - if (e.errors.any(e => e.detail === 'Not Found')) { - this - .controllerFor('application') - .set('nextFlashError', `User '${params.user_id}' does not exist`); - return this.replaceWith('index'); - } - } - ); - }, -}); - diff --git a/app/templates/user.hbs b/app/templates/user.hbs index 6b6b170f22a..26df555b240 100644 --- a/app/templates/user.hbs +++ b/app/templates/user.hbs @@ -1,16 +1,68 @@
    {{#user-link user=model}} - {{user-avatar user=model size='medium'}} + {{user-avatar user=model.user size='medium'}} {{/user-link}}

    - {{#link-to 'user' model}} - {{ model.login }} + {{#link-to 'user' model.user.login}} + {{ model.user.login }} {{/link-to}}

    - {{outlet}} + {{! TODO: reduce duplication with templates/crates.hbs }} + +
    + + +
    + Sort by + {{#rl-dropdown-container class="dropdown-container"}} + {{#rl-dropdown-toggle tagName="a" class="dropdown"}} + + {{ currentSortBy }} + + {{/rl-dropdown-toggle}} + + {{#rl-dropdown tagName="ul" class="dropdown" closeOnChildClick="a:link"}} +
  • + {{#link-to (query-params sort="alpha")}} + Alphabetical + {{/link-to}} +
  • +
  • + {{#link-to (query-params sort="downloads")}} + Downloads + {{/link-to}} +
  • + {{/rl-dropdown}} + {{/rl-dropdown-container}} +
    +
    + +
    + {{#each model.crates as |crate|}} + {{crate-row crate=crate}} + {{/each}} +
    + +
    diff --git a/app/templates/user/crates.hbs b/app/templates/user/crates.hbs deleted file mode 100644 index 3da7cdd9fb4..00000000000 --- a/app/templates/user/crates.hbs +++ /dev/null @@ -1,53 +0,0 @@ -{{! TODO: reduce duplication with templates/crates.hbs }} - -
    - - -
    - Sort by - {{#rl-dropdown-container class="dropdown-container"}} - {{#rl-dropdown-toggle tagName="a" class="dropdown"}} - - {{ currentSortBy }} - - {{/rl-dropdown-toggle}} - - {{#rl-dropdown tagName="ul" class="dropdown" closeOnChildClick="a:link"}} -
  • - {{#link-to (query-params sort="alpha")}} - Alphabetical - {{/link-to}} -
  • -
  • - {{#link-to (query-params sort="downloads")}} - Downloads - {{/link-to}} -
  • - {{/rl-dropdown}} - {{/rl-dropdown-container}} -
    -
    - -
    - {{#each model.crates as |crate|}} - {{crate-row crate=crate}} - {{/each}} -
    - - diff --git a/app/templates/user/index.hbs b/app/templates/user/index.hbs deleted file mode 100644 index 6a95ec24514..00000000000 --- a/app/templates/user/index.hbs +++ /dev/null @@ -1,7 +0,0 @@ -

    - Generic profile information here. -

    - -{{#link-to 'user.crates' model.login}} - See all their crates -{{/link-to}} From 0fbd282c3901f209248a6876e0e24116de741850 Mon Sep 17 00:00:00 2001 From: Kit La Touche Date: Thu, 15 Sep 2016 23:26:56 -0600 Subject: [PATCH 12/14] Move crate version owner link targets to Crates' own user pages --- app/templates/crate/version.hbs | 6 +++--- app/templates/user.hbs | 8 ++------ 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/app/templates/crate/version.hbs b/app/templates/crate/version.hbs index a39c698cd13..42356ec38ec 100644 --- a/app/templates/crate/version.hbs +++ b/app/templates/crate/version.hbs @@ -109,9 +109,9 @@
      {{#each crate.owners as |owner|}}
    • - {{#user-link user=owner}} - {{user-avatar user=owner size='medium-small'}} - {{/user-link}} + {{#link-to 'user' owner.login}} + {{user-avatar user=owner size='medium-small'}} + {{/link-to}}
    • {{/each}}
    diff --git a/app/templates/user.hbs b/app/templates/user.hbs index 26df555b240..5c215669628 100644 --- a/app/templates/user.hbs +++ b/app/templates/user.hbs @@ -1,11 +1,7 @@
    - {{#user-link user=model}} - {{user-avatar user=model.user size='medium'}} - {{/user-link}} + {{user-avatar user=model.user size='medium'}}

    - {{#link-to 'user' model.user.login}} - {{ model.user.login }} - {{/link-to}} + {{ model.user.login }}

    From 224c74163239a1c890652a590888d98a6981743b Mon Sep 17 00:00:00 2001 From: Kit La Touche Date: Sat, 17 Sep 2016 15:34:26 -0600 Subject: [PATCH 13/14] Add github profile link. --- app/templates/user.hbs | 3 +++ public/assets/GitHub-Mark-32px.png | Bin 0 -> 1714 bytes 2 files changed, 3 insertions(+) create mode 100644 public/assets/GitHub-Mark-32px.png diff --git a/app/templates/user.hbs b/app/templates/user.hbs index 5c215669628..70fc80623f2 100644 --- a/app/templates/user.hbs +++ b/app/templates/user.hbs @@ -3,6 +3,9 @@

    {{ model.user.login }}

    + {{#user-link user=model.user}} + GitHub profile + {{/user-link}}
    diff --git a/public/assets/GitHub-Mark-32px.png b/public/assets/GitHub-Mark-32px.png new file mode 100644 index 0000000000000000000000000000000000000000..8b25551a97921681334176ee143b41510a117d86 GIT binary patch literal 1714 zcmaJ?X;2eq7*4oFu!ne{XxAht2qc?8LXr|_LPCfTpaBK7K$c{I0Ld=NLIOeuC;@2) zZ$K%a)k+m-s0>xHmKxL%0V&0TRzzznhgyqrIC$F)0{WwLXLrBvd*^wc_uSc%h%m9E z{W5z3f#4_!7RvAyFh6!S_*<8qJ%KOIm?#E|L=rJQq=gB5C6WLG5;c?r%V0>EmEH#X z5eSwPRa6WXBMs#$5H%GtW2go-in9p>zW@UYDNNWc^XOXZQ? z1QjEV00I#$3^1wQUJ8&-2UsjB-G|9y(LDhMNN3PM{APL4eYi{(m*ERcUnJa{R+-3^ z34^A6;U^v`8N*O6ji%S@sd{fJqD`XFIUJ5zgTe5^5nj414F(y!G&=H(f)Lgzv?>%+ zAsWD}2qhpH7>|TU`X&W6IxDNuO_vET7|j5oG&&VDr!)hUO8+0KR?nh!m<)a!?|%yG zqOwq!CWCcIhE{<$E|F|@g>nP6FoYr6C<8>D?ID9%&5J(4oSbR1I^byW*g@__U z4QsF&uJSEcFeleM3~ChjEQGbHOjsGDMbyAl(p=Ttv9RaVo8~I#js@@Y9C^_2U})yn zzSHU%6FxuY?d;&65MyR({^lU*3$z$ZllDb(o&<7d;A_`h2U+3~BJ2Hv`{W}KEU801#cv_B|9Cm!ynR{S`AMsSn z;7E=B;mb!wx$L;S>yGXG^6=&WlQn9$s?&L%Y1D8TI^MlKB1DqsEng$>f4=xYWBoPI z_S1p!sJ#d2?YI4kPA{k}Eby?F=f-J9zIc`YDl^pzjVm~9ebE?Hn?t0Nx+la|D0MB; z9)2xv1G>a1|A9kQ>~DV<=X3-4yC&n!m8-3K#P z{X@0zRuQsy$+N ziSCoLJU{Z$nQy4A4Y5UJ07$5FA~qL2%Q+cLaqDU?Lz3?=BC5;Nk6BbTmmceEaM>-Z zi>O&-dSE=%ex;vcvCOk{*JQ5^_4M z4lW7%l9IqY(z7pV(?I@@8=KPFO82)O{VDI18-*d-k$YmI^XiuPs_LuFw<^ZcD}yP5 c*NrbeloN*74g`U%%F6r~k%+>C^#XapzmV0H-2eap literal 0 HcmV?d00001 From 6f7fc78bb95e9280b9de62ac00e22bf9d884378b Mon Sep 17 00:00:00 2001 From: Kit La Touche Date: Sun, 18 Sep 2016 18:59:24 -0600 Subject: [PATCH 14/14] Add padding around crate author heading --- app/styles/crate.scss | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/styles/crate.scss b/app/styles/crate.scss index 81aa6b3de9d..9e9d22d1192 100644 --- a/app/styles/crate.scss +++ b/app/styles/crate.scss @@ -11,7 +11,10 @@ @include display-flex; @include align-items(center); } - h1 { padding-left: 10px; } + h1 { + padding-left: 10px; + padding-right: 10px; + } h2 { color: $main-color-light; padding-left: 10px; } .right { @include flex(2);