Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FEATURE: Featured topic for user profile & card #8461

Merged
merged 15 commits into from Dec 9, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
@@ -1,5 +1,6 @@
import discourseComputed from "discourse-common/utils/decorators";
import { alias, or, and } from "@ember/object/computed";
import { propertyEqual } from "discourse/lib/computed";
import Component from "@ember/component";
import { getTopicFooterButtons } from "discourse/lib/register-topic-footer-button";

Expand All @@ -9,6 +10,11 @@ export default Component.extend({
// Allow us to extend it
layoutName: "components/topic-footer-buttons",

topicFeaturedOnProfile: propertyEqual(
"topic.id",
"currentUser.featured_topic.id"
),

@discourseComputed("topic.isPrivateMessage")
canArchive(isPM) {
return this.siteSettings.enable_personal_messages && isPM;
Expand Down Expand Up @@ -58,5 +64,19 @@ export default Component.extend({

@discourseComputed("topic.message_archived")
archiveLabel: archived =>
archived ? "topic.move_to_inbox.title" : "topic.archive_message.title"
archived ? "topic.move_to_inbox.title" : "topic.archive_message.title",

@discourseComputed(
"topic.user_id",
"topic.isPrivateMessage",
"topic.category.read_restricted"
)
showToggleFeatureOnProfileButton(userId, isPm, restricted) {
return (
this.siteSettings.allow_featured_topic_on_user_profiles &&
userId === this.currentUser.get("id") &&
!restricted &&
!isPm
);
}
});
Expand Up @@ -50,6 +50,11 @@ export default Component.extend(CardContentsBase, CanCheckEmails, CleansUp, {
// If inside a topic
topicPostCount: null,

showFeaturedTopic: and(
"user.featured_topic",
"siteSettings.allow_featured_topic_on_user_profiles"
),

markvanlan marked this conversation as resolved.
Show resolved Hide resolved
@discourseComputed("user.staff")
staff: isStaff => (isStaff ? "staff" : ""),

Expand Down
17 changes: 17 additions & 0 deletions app/assets/javascripts/discourse/controllers/topic.js.es6
Expand Up @@ -679,6 +679,19 @@ export default Controller.extend(bufferedProperty("model"), {
}
},

toggleFeaturedOnProfile() {
if (!this.currentUser) return;

if (
this.currentUser.featured_topic &&
this.currentUser.featured_topic.id !== this.model.id
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could be simplify by:

this.get("currentUser.featured_topic.id") !== this.model.id

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These statements are not equivalent, and does not work for what I need.

I do not want to entire this branch of the if, when the featured_topic is null. this.get("currentUser.featured_topic.id") !== this.model.id evaluates to true when the featured_topic is null.

) {
bootbox.confirm(I18n.t("topic.remove_from_profile.warning"), result => {
if (result) return this._performToggleFeaturedOnProfile();
});
} else return this._performToggleFeaturedOnProfile();
},

jumpToIndex(index) {
this._jumpToIndex(index);
},
Expand Down Expand Up @@ -1070,6 +1083,10 @@ export default Controller.extend(bufferedProperty("model"), {
}
},

_performToggleFeaturedOnProfile() {
this.model.toggleFeaturedOnProfile(this.currentUser).catch(popupAjaxError);
},

_jumpToIndex(index) {
const postStream = this.get("model.postStream");

Expand Down
5 changes: 5 additions & 0 deletions app/assets/javascripts/discourse/controllers/user.js.es6
Expand Up @@ -61,6 +61,11 @@ export default Controller.extend(CanCheckEmails, {
"hasReceivedWarnings"
),

showFeaturedTopic: and(
"model.featured_topic",
"siteSettings.allow_featured_topic_on_user_profiles"
),

@discourseComputed("model.suspended", "currentUser.staff")
isNotSuspendedOrIsStaff(suspended, isStaff) {
return !suspended || isStaff;
Expand Down
Expand Up @@ -166,5 +166,34 @@ export default {
return this.site.mobileView;
}
});

registerTopicFooterButton({
dependentKeys: ["currentUser.featured_topic"],
id: "toggle-feature-on-profile",
icon: "id-card",
priority: 300,
label() {
return this.topicFeaturedOnProfile
? "topic.remove_from_profile.title"
: "topic.feature_on_profile.title";
},
title() {
return this.topicFeaturedOnProfile
? "topic.remove_from_profile.help"
: "topic.feature_on_profile.help";
},
classNames() {
return this.topicFeaturedOnProfile
? ["feature-on-profile", "featured-on-profile"]
: ["feature-on-profile"];
},
action: "toggleFeaturedOnProfile",
displayed() {
return this.showToggleFeatureOnProfileButton;
},
dropdown() {
return this.site.mobileView;
}
});
}
};
15 changes: 15 additions & 0 deletions app/assets/javascripts/discourse/models/topic.js.es6
Expand Up @@ -444,6 +444,21 @@ const Topic = RestModel.extend({
});
},

toggleFeaturedOnProfile(user) {
const removing = user.get("featured_topic.id") === this.id;
const path = removing ? "clear-featured-topic" : "feature-topic";
return ajax(`/u/${user.username}/${path}`, {
type: "PUT",
data: { topic_id: this.id }
})
.then(() => {
const featuredTopic = removing ? null : this;
user.set("featured_topic", featuredTopic);
return;
})
.catch(popupAjaxError);
},

createGroupInvite(group) {
return ajax(`/t/${this.id}/invite-group`, {
type: "POST",
Expand Down
Expand Up @@ -10,13 +10,13 @@
<div class="card-row second-row">
<div class="animated-placeholder placeholder-animation"></div>
</div>
<div class="card-row third-row">
<div class="card-row">
<div class="animated-placeholder placeholder-animation"></div>
</div>
<div class="card-row fourth-row">
<div class="card-row">
<div class="animated-placeholder placeholder-animation"></div>
</div>
<div class="card-row sixth-row">
<div class="card-row">
<div class="animated-placeholder placeholder-animation"></div>
</div>
{{else}}
Expand Down Expand Up @@ -140,8 +140,17 @@
</div>
{{/if}}

{{#if showFeaturedTopic}}
<div class="card-row">
<div class="featured-topic">
<span class="desc">{{i18n 'user.featured_topic'}}</span>
{{#link-to "topic" user.featured_topic.slug user.featured_topic.id }}{{user.featured_topic.fancy_title}}{{/link-to}}
</div>
</div>
{{/if}}

{{#if hasLocationOrWebsite}}
<div class="card-row third-row">
<div class="card-row">
<div class="location-and-website">
{{#if user.location}}
<span class='location'>{{d-icon "map-marker-alt"}}
Expand All @@ -163,7 +172,7 @@
</div>
{{/if}}

<div class="card-row fourth-row">
<div class="card-row">
{{#unless user.profile_hidden}}
<div class="metadata">
{{#if user.last_posted_at}}
Expand Down Expand Up @@ -203,7 +212,7 @@
</div>

{{#if publicUserFields}}
<div class="card-row fifth-row">
<div class="card-row">
<div class="public-user-fields">
{{#each publicUserFields as |uf|}}
{{#if uf.value}}
Expand All @@ -220,7 +229,7 @@
{{plugin-outlet name="user-card-before-badges" args=(hash user=user)}}

{{#if showBadges}}
<div class="card-row sixth-row">
<div class="card-row">
{{#if user.featured_user_badges}}
<div class="badge-section">
{{#each user.featured_user_badges as |ub|}}
Expand Down
12 changes: 12 additions & 0 deletions app/assets/javascripts/discourse/templates/preferences/profile.hbs
Expand Up @@ -57,6 +57,18 @@
</div>
{{/if}}

{{#if model.featured_topic}}
<div class="control-group">
<label class="control-label">{{i18n 'user.featured_topic'}}</label>
<label class="control-label">
{{#link-to "topic" model.featured_topic.slug model.featured_topic.id}}{{model.featured_topic.fancy_title}}{{/link-to}}
</label>
<div class='instructions'>
{{i18n 'user.change_featured_topic.instructions'}}
</div>
</div>
{{/if}}

{{plugin-outlet name="user-preferences-profile" args=(hash model=model save=(action "save"))}}

{{plugin-outlet name="user-custom-preferences" args=(hash model=model)}}
Expand Down
3 changes: 2 additions & 1 deletion app/assets/javascripts/discourse/templates/topic.hbs
Expand Up @@ -313,7 +313,8 @@
toggleArchiveMessage=(action "toggleArchiveMessage")
editFirstPost=(action "editFirstPost")
deferTopic=(action "deferTopic")
replyToPost=(action "replyToPost")}}
replyToPost=(action "replyToPost")
toggleFeaturedOnProfile=(action "toggleFeaturedOnProfile")}}
{{else}}
<div id="topic-footer-buttons">
{{d-button icon="reply" class="btn-primary pull-right" action=(route-action "showLogin") label="topic.reply.title"}}
Expand Down
8 changes: 8 additions & 0 deletions app/assets/javascripts/discourse/templates/user.hbs
Expand Up @@ -92,6 +92,14 @@
{{/if}}
{{plugin-outlet name="user-post-names" args=(hash model=model)}}
</div>

{{#if showFeaturedTopic}}
<h3 class="featured-topic">
<span>{{i18n 'user.featured_topic'}}</span>
{{#link-to "topic" model.featured_topic.slug model.featured_topic.id}}{{model.featured_topic.fancy_title}}{{/link-to}}
</h3>
{{/if}}

<h3 class="location-and-website">
{{#if model.location}}<div class="user-profile-location">{{d-icon "map-marker-alt"}} {{model.location}}</div>{{/if}}
{{#if model.website_name}}
Expand Down
88 changes: 47 additions & 41 deletions app/assets/stylesheets/common/components/user-card.scss
Expand Up @@ -181,56 +181,62 @@ $avatar_margin: -50px; // negative margin makes avatars extend above cards
margin-top: 0.5em;
}
}
// featured topic
.featured-topic {
.desc {
color: $primary-high;
}
a {
color: $primary;
text-decoration: underline;
}
}

// location and website
.third-row {
.location-and-website {
.location-and-website {
display: flex;
flex-wrap: wrap;
width: 100%;
align-items: center;
.location,
.website-name {
display: flex;
flex-wrap: wrap;
width: 100%;
overflow: hidden;
align-items: center;
.location,
.website-name {
display: flex;
overflow: hidden;
align-items: center;
.d-icon {
margin-right: 0.25em;
}
}
.website-name a,
.location span {
@include ellipsis;
color: $primary;
}
.location {
margin-right: 0.5em;
}
.website-name a {
text-decoration: underline;
.d-icon {
margin-right: 0.25em;
}
}
.website-name a,
.location span {
@include ellipsis;
color: $primary;
}
.location {
margin-right: 0.5em;
}
.website-name a {
text-decoration: underline;
}
}
// custom user fields
.fifth-row {
.public-user-fields {
margin: 0;
}
.public-user-fields {
margin: 0;
}

// badges
.sixth-row {
.badge-section {
display: flex;
align-items: flex-start;
.user-badge {
@include ellipsis;
background: $primary-very-low;
border: 1px solid $primary-low;
color: $primary;
}
.more-user-badges {
a {
@extend .user-badge;
}
.badge-section {
display: flex;
align-items: flex-start;
.user-badge {
@include ellipsis;
background: $primary-very-low;
border: 1px solid $primary-low;
color: $primary;
}
.more-user-badges {
a {
@extend .user-badge;
}
}
}
Expand Down
18 changes: 8 additions & 10 deletions app/assets/stylesheets/desktop/components/user-card.scss
Expand Up @@ -37,16 +37,14 @@
// styles for user cards only
#user-card {
// badges
.sixth-row {
.badge-section {
.user-badge {
display: block;
max-width: 185px;
margin: 0 0.5em 0 0;
}
.more-user-badges {
max-width: 125px;
}
.badge-section {
.user-badge {
display: block;
max-width: 185px;
margin: 0 0.5em 0 0;
}
.more-user-badges {
max-width: 125px;
}
}
}
3 changes: 3 additions & 0 deletions app/assets/stylesheets/desktop/topic-post.scss
Expand Up @@ -451,6 +451,9 @@ nav.post-controls {
.bookmark.bookmarked .d-icon-bookmark {
color: $tertiary;
}
.feature-on-profile.featured-on-profile .d-icon-id-card {
color: $tertiary;
}
}

#topic-footer-button {
Expand Down