From 9c4a1ecd6805ec03b3e54dce700521a9020aec63 Mon Sep 17 00:00:00 2001 From: David Taylor Date: Mon, 9 Mar 2020 16:37:29 +0000 Subject: [PATCH] Add stats, add filters, add time period selector, fix mobile view --- common/common.scss | 86 +++++++++++-- .../initializers/user-card-directory.js.es6 | 117 ++++++++++++------ javascripts/discourse/templates/users.hbs | 28 ++++- locales/en.yml | 3 +- 4 files changed, 179 insertions(+), 55 deletions(-) diff --git a/common/common.scss b/common/common.scss index e35c580..2719dc2 100644 --- a/common/common.scss +++ b/common/common.scss @@ -1,17 +1,79 @@ +.directory { + .filter-name { + float: none; + } + + .filters { + display: flex; + justify-content: space-between; + flex-wrap: wrap; + + > span { + margin-bottom: 5px; + } + } + + .group-filter:not(.active) .select-kit-header { + color: $primary-high; + } +} .user-card-directory { + display: flex; + flex-wrap: wrap; + justify-content: center; + + .user-card { + z-index: z("base"); + position: relative; + left: auto; + width: 100%; + box-shadow: none; + margin: 0; + + .badge-section { + overflow: hidden; + } + } + + .usercard-controls { + display: none; + } + + .user-card-container { + // width: calc(50% - 40px); + flex-grow: 1; + // flex-basis: min-content; + // width: 500px; + margin: 50px 5px 10px 5px; + background-color: $secondary; + box-shadow: shadow("card"); + margin-bottom: auto; + } + + .user-card-directory-footer { + background-color: $secondary; + padding: 0px 10px 10px 10px; display: flex; flex-wrap: wrap; - justify-content: center; - - .user-card { - position: relative; - left: auto; - width: 100%; + + .stat { + flex-basis: 0; + flex-grow: 1; + + display: flex; + flex-direction: column; + align-items: center; + margin: 2px; + + .label { + font-size: $font-down-2; + + .d-icon { + margin-right: 0.2em; + color: $primary-medium; + } + } } - - .user-card-container { - width: calc(50% - 40px); - margin: 50px 20px 10px 20px; - } - } \ No newline at end of file + } +} diff --git a/javascripts/discourse/initializers/user-card-directory.js.es6 b/javascripts/discourse/initializers/user-card-directory.js.es6 index 5cf620f..36459d4 100644 --- a/javascripts/discourse/initializers/user-card-directory.js.es6 +++ b/javascripts/discourse/initializers/user-card-directory.js.es6 @@ -6,54 +6,91 @@ import { ajax } from "discourse/lib/ajax"; export default { name: "user-card-directory", - initialize(){ + initialize(container) { + // This component provides a responsive template + // Delete the core mobile one + delete Ember.TEMPLATES["mobile/users"]; + withPluginApi("0.8.7", api => { + api.modifyClass("route:users", { + resetController(controller, isExisting) { + this._super(controller, isExisting); + if (isExisting) { + controller.set("cachedUserCardInfo", {}); + } + } + }); + api.modifyClass("controller:users", { cachedUserCardInfo: {}, - + + stats: [ + { name: "likes_received", icon: "heart" }, + { name: "likes_given", icon: "heart" }, + { name: "topic_count" }, + { name: "post_count" }, + { name: "topics_entered" }, + { name: "posts_read" }, + { name: "days_visited" } + ], + + @discourseComputed("site.groups") + availableGroups(groups) { + return groups + .map(g => { + // prevents group "everyone" to be listed + if (g.id !== 0) { + return { name: g.name, value: g.name }; + } + }) + .filter(Boolean); + }, + @discourseComputed("model.content.@each") userCards(allUsers) { - const toLoad = []; - const userCardInfos = allUsers.map(u => { - if (this.cachedUserCardInfo[u.id]) { - return this.cachedUserCardInfo[u.id]; - } - - const userCardInfo = this.cachedUserCardInfo[u.id] = EmberObject.create({ - user: User.create(u.user), - loading: true - }); - - toLoad.push(userCardInfo); - - return userCardInfo; - }); - - const loadMax = 50; - - while (toLoad.length > 0) { - const thisBatch = toLoad.splice(0, loadMax); - const promise = ajax("/user-cards.json", { - data: { user_ids: thisBatch.map(uc => uc.user.id).join(",") } - }); - thisBatch.forEach(uc => { - const convertedPromise = promise.then(data => { - // Find the correct user from users, and put it in the user attribute - // Use Object.assign to avoid contaminating the source object - return Object.assign({}, data, { - user: data.users.find(u => u.id === uc.user.id) - }); - }); - return uc.user - .findDetails({ existingRequest: convertedPromise }) - .then(() => uc.set("loading", false)); - }); + const toLoad = []; + const userCardInfos = allUsers.map(u => { + if (this.cachedUserCardInfo[u.id]) { + return this.cachedUserCardInfo[u.id]; } - return userCardInfos; - } + const userCardInfo = (this.cachedUserCardInfo[ + u.id + ] = EmberObject.create({ + user: User.create(u.user), + directoryItem: u, + loading: true + })); + toLoad.push(userCardInfo); + + return userCardInfo; + }); + + const loadMax = 50; + + while (toLoad.length > 0) { + const thisBatch = toLoad.splice(0, loadMax); + const promise = ajax("/user-cards.json", { + data: { user_ids: thisBatch.map(uc => uc.user.id).join(",") } + }); + thisBatch.forEach(uc => { + const convertedPromise = promise.then(data => { + // Find the correct user from users, and put it in the user attribute + // Use Object.assign to avoid contaminating the source object + return Object.assign({}, data, { + user: data.users.find(u => u.id === uc.user.id) + }); + }); + return uc.user + .findDetails({ existingRequest: convertedPromise }) + .then(() => uc.set("loading", false)); + }); + } + + return userCardInfos; + } }); }); } -} +}; diff --git a/javascripts/discourse/templates/users.hbs b/javascripts/discourse/templates/users.hbs index e576f2c..425e6d2 100644 --- a/javascripts/discourse/templates/users.hbs +++ b/javascripts/discourse/templates/users.hbs @@ -3,8 +3,20 @@
{{plugin-outlet name="users-top" connectorTagName='div' args=(hash model=model)}} -
- {{text-field value=nameInput placeholderKey="directory.filter_name" class="filter-name no-blur"}} + +
+ {{period-chooser period=period onChange=(action (mut period))}} +
+
+ + {{combo-box content=availableGroups + value=group + options=(hash clearable=true none=(theme-prefix 'filter_by_group')) + valueAttribute="value"}} + + + {{text-field value=nameInput placeholderKey="directory.filter_name" class="filter-name no-blur"}} +
{{#conditional-loading-spinner condition=model.loading}} @@ -18,6 +30,18 @@ loading=userCard.loading username=userCard.user.username }} +
{{/each}}
diff --git a/locales/en.yml b/locales/en.yml index 70619cd..de21431 100644 --- a/locales/en.yml +++ b/locales/en.yml @@ -1,3 +1,4 @@ en: theme_metadata: - description: Replaces the user directory with a grid of user cards \ No newline at end of file + description: Replaces the user directory with a grid of user cards + filter_by_group: filter by group \ No newline at end of file