FEATURE: Let users select flair (#13587)
User flair was given by user's primary group. This PR separates the two, adds a new field to the user model for flair group ID and users can select their flair from user preferences now.
This commit is contained in:
parent
c6f2459cc4
commit
87c1e98571
|
@ -4,17 +4,17 @@ import { observes } from "discourse-common/utils/decorators";
|
|||
export default MountWidget.extend({
|
||||
widget: "avatar-flair",
|
||||
|
||||
@observes("flairURL", "flairBgColor", "flairColor")
|
||||
@observes("flairName", "flairUrl", "flairBgColor", "flairColor")
|
||||
_rerender() {
|
||||
this.queueRerender();
|
||||
},
|
||||
|
||||
buildArgs() {
|
||||
return {
|
||||
primary_group_flair_url: this.flairURL,
|
||||
primary_group_flair_bg_color: this.flairBgColor,
|
||||
primary_group_flair_color: this.flairColor,
|
||||
primary_group_name: this.groupName,
|
||||
flair_name: this.flairName,
|
||||
flair_url: this.flairUrl,
|
||||
flair_bg_color: this.flairBgColor,
|
||||
flair_color: this.flairColor,
|
||||
};
|
||||
},
|
||||
});
|
||||
|
|
|
@ -67,8 +67,8 @@ export default Component.extend({
|
|||
},
|
||||
|
||||
@discourseComputed("model.flair_url")
|
||||
flairImageUrl(flairURL) {
|
||||
return flairURL && flairURL.match(/\//) ? flairURL : null;
|
||||
flairImageUrl(flairUrl) {
|
||||
return flairUrl && flairUrl.includes("/") ? flairUrl : null;
|
||||
},
|
||||
|
||||
@discourseComputed(
|
||||
|
@ -78,7 +78,7 @@ export default Component.extend({
|
|||
"model.flairHexColor"
|
||||
)
|
||||
flairPreviewStyle(
|
||||
flairURL,
|
||||
flairUrl,
|
||||
flairPreviewImage,
|
||||
flairBackgroundHexColor,
|
||||
flairHexColor
|
||||
|
@ -86,7 +86,7 @@ export default Component.extend({
|
|||
let style = "";
|
||||
|
||||
if (flairPreviewImage) {
|
||||
style += `background-image: url(${escapeExpression(flairURL)});`;
|
||||
style += `background-image: url(${escapeExpression(flairUrl)});`;
|
||||
}
|
||||
|
||||
if (flairBackgroundHexColor) {
|
||||
|
|
|
@ -10,28 +10,23 @@ export default Component.extend({
|
|||
if (!user) {
|
||||
return;
|
||||
}
|
||||
return this.primaryGroupFlair(user) || this.automaticGroupFlair(user);
|
||||
},
|
||||
|
||||
primaryGroupFlair(user) {
|
||||
if (user.primary_group_flair_url || user.primary_group_flair_bg_color) {
|
||||
if (user.flair_url || user.flair_bg_color) {
|
||||
return {
|
||||
flairURL: user.primary_group_flair_url,
|
||||
flairBgColor: user.primary_group_flair_bg_color,
|
||||
flairColor: user.primary_group_flair_color,
|
||||
groupName: user.primary_group_name,
|
||||
flairName: user.flair_name,
|
||||
flairUrl: user.flair_url,
|
||||
flairBgColor: user.flair_bg_color,
|
||||
flairColor: user.flair_color,
|
||||
};
|
||||
}
|
||||
},
|
||||
|
||||
automaticGroupFlair(user) {
|
||||
const autoFlairAttrs = autoGroupFlairForUser(this.site, user);
|
||||
if (autoFlairAttrs) {
|
||||
return {
|
||||
flairURL: autoFlairAttrs.primary_group_flair_url,
|
||||
flairBgColor: autoFlairAttrs.primary_group_flair_bg_color,
|
||||
flairColor: autoFlairAttrs.primary_group_flair_color,
|
||||
groupName: autoFlairAttrs.primary_group_name,
|
||||
flairName: autoFlairAttrs.flair_name,
|
||||
flairUrl: autoFlairAttrs.flair_url,
|
||||
flairBgColor: autoFlairAttrs.flair_bg_color,
|
||||
flairColor: autoFlairAttrs.flair_color,
|
||||
};
|
||||
}
|
||||
},
|
||||
|
|
|
@ -101,21 +101,6 @@ export default Controller.extend({
|
|||
return (fullName || displayName).capitalize();
|
||||
},
|
||||
|
||||
@discourseComputed(
|
||||
"model.name",
|
||||
"model.flair_url",
|
||||
"model.flair_bg_color",
|
||||
"model.flair_color"
|
||||
)
|
||||
avatarFlairAttributes(groupName, flairURL, flairBgColor, flairColor) {
|
||||
return {
|
||||
primary_group_flair_url: flairURL,
|
||||
primary_group_flair_bg_color: flairBgColor,
|
||||
primary_group_flair_color: flairColor,
|
||||
primary_group_name: groupName,
|
||||
};
|
||||
},
|
||||
|
||||
@discourseComputed("model.messageable")
|
||||
displayGroupMessageButton(messageable) {
|
||||
return this.currentUser && messageable;
|
||||
|
|
|
@ -15,7 +15,12 @@ export default Controller.extend(CanCheckEmails, {
|
|||
init() {
|
||||
this._super(...arguments);
|
||||
|
||||
this.saveAttrNames = ["name", "title", "primary_group_id"];
|
||||
this.saveAttrNames = [
|
||||
"name",
|
||||
"title",
|
||||
"primary_group_id",
|
||||
"flair_group_id",
|
||||
];
|
||||
this.set("revoking", {});
|
||||
},
|
||||
|
||||
|
@ -45,6 +50,7 @@ export default Controller.extend(CanCheckEmails, {
|
|||
},
|
||||
|
||||
canSelectTitle: gt("model.availableTitles.length", 0),
|
||||
canSelectFlair: gt("model.availableFlairs.length", 0),
|
||||
|
||||
@discourseComputed("model.filteredGroups")
|
||||
canSelectPrimaryGroup(primaryGroupOptions) {
|
||||
|
@ -132,6 +138,7 @@ export default Controller.extend(CanCheckEmails, {
|
|||
name: this.newNameInput,
|
||||
title: this.newTitleInput,
|
||||
primary_group_id: this.newPrimaryGroupInput,
|
||||
flair_group_id: this.newFlairGroupId,
|
||||
});
|
||||
|
||||
return this.model
|
||||
|
|
|
@ -56,10 +56,10 @@ function initializeAutoGroupFlair(site) {
|
|||
if (group && group.flair_url) {
|
||||
_noAutoFlair = false;
|
||||
_autoGroupFlair[groupName] = {
|
||||
primary_group_flair_url: group.flair_url,
|
||||
primary_group_flair_bg_color: group.flair_bg_color,
|
||||
primary_group_flair_color: group.flair_color,
|
||||
primary_group_name: group.name.replace(/_/g, " "),
|
||||
flair_name: group.name.replace(/_/g, " "),
|
||||
flair_url: group.flair_url,
|
||||
flair_bg_color: group.flair_bg_color,
|
||||
flair_color: group.flair_color,
|
||||
};
|
||||
}
|
||||
});
|
||||
|
|
|
@ -21,9 +21,10 @@ export function transformBasicPost(post) {
|
|||
deletedByAvatarTemplate: null,
|
||||
deletedByUsername: null,
|
||||
primary_group_name: post.primary_group_name,
|
||||
primary_group_flair_url: post.primary_group_flair_url,
|
||||
primary_group_flair_bg_color: post.primary_group_flair_bg_color,
|
||||
primary_group_flair_color: post.primary_group_flair_color,
|
||||
flair_name: post.flair_name,
|
||||
flair_url: post.flair_url,
|
||||
flair_bg_color: post.flair_bg_color,
|
||||
flair_color: post.flair_color,
|
||||
wiki: post.wiki,
|
||||
lastWikiEdit: post.last_wiki_edit,
|
||||
firstPost: post.post_number === 1,
|
||||
|
|
|
@ -59,6 +59,7 @@ let userFields = [
|
|||
"watching_first_post_tags",
|
||||
"date_of_birth",
|
||||
"primary_group_id",
|
||||
"flair_group_id",
|
||||
"user_notification_schedule",
|
||||
];
|
||||
|
||||
|
@ -863,7 +864,7 @@ const User = RestModel.extend({
|
|||
|
||||
@discourseComputed("groups.@each.title", "badges.[]")
|
||||
availableTitles() {
|
||||
let titles = [];
|
||||
const titles = [];
|
||||
|
||||
(this.groups || []).forEach((group) => {
|
||||
if (get(group, "title")) {
|
||||
|
@ -888,6 +889,27 @@ const User = RestModel.extend({
|
|||
});
|
||||
},
|
||||
|
||||
@discourseComputed("groups.[]")
|
||||
availableFlairs() {
|
||||
const flairs = [];
|
||||
|
||||
if (this.groups) {
|
||||
this.groups.forEach((group) => {
|
||||
if (group.flair_url) {
|
||||
flairs.push({
|
||||
id: group.id,
|
||||
name: group.name,
|
||||
url: group.flair_url,
|
||||
bgColor: group.flair_bg_color,
|
||||
color: group.flair_color,
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return flairs;
|
||||
},
|
||||
|
||||
@discourseComputed("user_option.text_size_seq", "user_option.text_size")
|
||||
currentTextSize(serverSeq, serverSize) {
|
||||
if (cookie("text_size")) {
|
||||
|
|
|
@ -29,6 +29,7 @@ export default RestrictedUserRoute.extend({
|
|||
newNameInput: user.get("name"),
|
||||
newTitleInput: user.get("title"),
|
||||
newPrimaryGroupInput: user.get("primary_group_id"),
|
||||
newFlairGroupId: user.get("flair_group_id"),
|
||||
});
|
||||
},
|
||||
|
||||
|
|
|
@ -4,10 +4,10 @@
|
|||
<div class="group-card-avatar">
|
||||
<a href={{groupPath}} {{action "showGroup" group}} class="card-huge-avatar">
|
||||
{{avatar-flair
|
||||
flairURL=group.flair_url
|
||||
flairName=group.name
|
||||
flairUrl=group.flair_url
|
||||
flairBgColor=group.flair_bg_color
|
||||
flairColor=group.flair_color
|
||||
groupName=group.name
|
||||
}}
|
||||
</a>
|
||||
</div>
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
{{#if flair}}
|
||||
{{avatar-flair
|
||||
flairURL=flair.flairURL
|
||||
flairName=flair.flairName
|
||||
flairUrl=flair.flairUrl
|
||||
flairBgColor=flair.flairBgColor
|
||||
flairColor=flair.flairColor
|
||||
groupName=flair.groupName}}
|
||||
}}
|
||||
{{/if}}
|
||||
|
|
|
@ -12,10 +12,10 @@
|
|||
{{#if model.flair_url}}
|
||||
<div class="group-avatar-flair">
|
||||
{{avatar-flair
|
||||
flairURL=model.flair_url
|
||||
flairName=model.name
|
||||
flairUrl=model.flair_url
|
||||
flairBgColor=model.flair_bg_color
|
||||
flairColor=model.flair_color
|
||||
groupName=model.name
|
||||
}}
|
||||
</div>
|
||||
{{/if}}
|
||||
|
|
|
@ -44,10 +44,11 @@
|
|||
{{#if group.flair_url}}
|
||||
<span class="group-avatar-flair">
|
||||
{{avatar-flair
|
||||
flairURL=group.flair_url
|
||||
flairBgColor=group.flair_bg_color
|
||||
flairColor=group.flair_color
|
||||
groupName=group.name}}
|
||||
flairName=group.name
|
||||
flairUrl=group.flair_url
|
||||
flairBgColor=group.flair_bg_color
|
||||
flairColor=group.flair_color
|
||||
}}
|
||||
</span>
|
||||
{{/if}}
|
||||
|
||||
|
|
|
@ -158,6 +158,26 @@
|
|||
onChange=(action (mut newTitleInput))
|
||||
}}
|
||||
</div>
|
||||
<div class="instructions">
|
||||
{{i18n "user.title.instructions"}}
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
{{#if canSelectFlair}}
|
||||
<div class="control-group pref-flair">
|
||||
<label class="control-label">{{i18n "user.flair.title"}}</label>
|
||||
<div class="controls">
|
||||
{{flair-chooser
|
||||
value=newFlairGroupId
|
||||
content=model.availableFlairs
|
||||
none="user.flair.none"
|
||||
onChange=(action (mut newFlairGroupId))
|
||||
}}
|
||||
</div>
|
||||
<div class="instructions">
|
||||
{{i18n "user.flair.instructions"}}
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
|
|
|
@ -6,19 +6,16 @@ createWidget("avatar-flair", {
|
|||
tagName: "div.avatar-flair",
|
||||
|
||||
isIcon(attrs) {
|
||||
return (
|
||||
attrs.primary_group_flair_url &&
|
||||
!attrs.primary_group_flair_url.includes("/")
|
||||
);
|
||||
return attrs.flair_url && !attrs.flair_url.includes("/");
|
||||
},
|
||||
|
||||
title(attrs) {
|
||||
return attrs.primary_group_name;
|
||||
return attrs.flair_name;
|
||||
},
|
||||
|
||||
buildClasses(attrs) {
|
||||
let defaultClass = `avatar-flair-${attrs.primary_group_name} ${
|
||||
attrs.primary_group_flair_bg_color ? "rounded" : ""
|
||||
let defaultClass = `avatar-flair-${attrs.flair_name} ${
|
||||
attrs.flair_bg_color ? "rounded" : ""
|
||||
}`;
|
||||
|
||||
if (!this.isIcon(attrs)) {
|
||||
|
@ -32,26 +29,21 @@ createWidget("avatar-flair", {
|
|||
let style = "";
|
||||
if (!this.isIcon(attrs)) {
|
||||
style +=
|
||||
"background-image: url(" +
|
||||
escapeExpression(attrs.primary_group_flair_url) +
|
||||
"); ";
|
||||
"background-image: url(" + escapeExpression(attrs.flair_url) + "); ";
|
||||
}
|
||||
if (attrs.primary_group_flair_bg_color) {
|
||||
if (attrs.flair_bg_color) {
|
||||
style +=
|
||||
"background-color: #" +
|
||||
escapeExpression(attrs.primary_group_flair_bg_color) +
|
||||
"; ";
|
||||
"background-color: #" + escapeExpression(attrs.flair_bg_color) + "; ";
|
||||
}
|
||||
if (attrs.primary_group_flair_color) {
|
||||
style +=
|
||||
"color: #" + escapeExpression(attrs.primary_group_flair_color) + "; ";
|
||||
if (attrs.flair_color) {
|
||||
style += "color: #" + escapeExpression(attrs.flair_color) + "; ";
|
||||
}
|
||||
return { style: style };
|
||||
return { style };
|
||||
},
|
||||
|
||||
html(attrs) {
|
||||
if (this.isIcon(attrs)) {
|
||||
const icon = convertIconClass(attrs.primary_group_flair_url);
|
||||
const icon = convertIconClass(attrs.flair_url);
|
||||
return [iconNode(icon)];
|
||||
} else {
|
||||
return [];
|
||||
|
|
|
@ -187,7 +187,7 @@ createWidget("post-avatar", {
|
|||
|
||||
const result = [body];
|
||||
|
||||
if (attrs.primary_group_flair_url || attrs.primary_group_flair_bg_color) {
|
||||
if (attrs.flair_url || attrs.flair_bg_color) {
|
||||
result.push(this.attach("avatar-flair", attrs));
|
||||
} else {
|
||||
const autoFlairAttrs = autoGroupFlairForUser(this.site, attrs);
|
||||
|
|
|
@ -102,10 +102,10 @@ createSearchResult({
|
|||
let avatarFlair;
|
||||
if (group.flairUrl) {
|
||||
avatarFlair = this.attach("avatar-flair", {
|
||||
primary_group_flair_url: group.flairUrl,
|
||||
primary_group_flair_bg_color: group.flairBgColor,
|
||||
primary_group_flair_color: group.flairColor,
|
||||
primary_group_name: name,
|
||||
flair_name: name,
|
||||
flair_url: group.flairUrl,
|
||||
flair_bg_color: group.flairBgColor,
|
||||
flair_color: group.flairColor,
|
||||
});
|
||||
} else {
|
||||
avatarFlair = iconNode("users");
|
||||
|
|
|
@ -79,7 +79,7 @@ createWidget("topic-participant", {
|
|||
linkContents.push(h("span.post-count", attrs.post_count.toString()));
|
||||
}
|
||||
|
||||
if (attrs.primary_group_flair_url || attrs.primary_group_flair_bg_color) {
|
||||
if (attrs.flair_url || attrs.flair_bg_color) {
|
||||
linkContents.push(this.attach("avatar-flair", attrs));
|
||||
} else {
|
||||
const autoFlairAttrs = autoGroupFlairForUser(this.site, attrs);
|
||||
|
|
|
@ -571,9 +571,10 @@ export default {
|
|||
topic_slug: "14-the-title-must-be-longer-i-guess",
|
||||
display_username: "",
|
||||
primary_group_name: "Team",
|
||||
primary_group_flair_url: null,
|
||||
primary_group_flair_bg_color: "",
|
||||
primary_group_flair_color: "",
|
||||
flair_name: null,
|
||||
flair_url: null,
|
||||
flair_bg_color: "",
|
||||
flair_color: "",
|
||||
version: 1,
|
||||
can_edit: false,
|
||||
can_delete: false,
|
||||
|
@ -711,9 +712,10 @@ export default {
|
|||
avatar_template: "/user_avatar/localhost/markvanlan/{size}/11_2.png",
|
||||
post_count: 1,
|
||||
primary_group_name: "Team",
|
||||
primary_group_flair_url: null,
|
||||
primary_group_flair_color: "",
|
||||
primary_group_flair_bg_color: ""
|
||||
flair_name: null,
|
||||
flair_url: null,
|
||||
flair_color: "",
|
||||
flair_bg_color: ""
|
||||
}
|
||||
],
|
||||
created_by: {
|
||||
|
|
|
@ -21,9 +21,10 @@ export default {
|
|||
topic_slug: "test-pm",
|
||||
display_username: null,
|
||||
primary_group_name: null,
|
||||
primary_group_flair_url: null,
|
||||
primary_group_flair_bg_color: null,
|
||||
primary_group_flair_color: null,
|
||||
flair_name: null,
|
||||
flair_url: null,
|
||||
flair_bg_color: null,
|
||||
flair_color: null,
|
||||
version: 1,
|
||||
can_edit: true,
|
||||
can_delete: false,
|
||||
|
|
|
@ -27,9 +27,10 @@ export default {
|
|||
topic_slug: "lorem-ipsum-dolor-sit-amet",
|
||||
display_username: null,
|
||||
primary_group_name: null,
|
||||
primary_group_flair_url: null,
|
||||
primary_group_flair_bg_color: null,
|
||||
primary_group_flair_color: null,
|
||||
flair_name: null,
|
||||
flair_url: null,
|
||||
flair_bg_color: null,
|
||||
flair_color: null,
|
||||
version: 1,
|
||||
can_edit: true,
|
||||
can_delete: false,
|
||||
|
@ -167,9 +168,10 @@ export default {
|
|||
avatar_template: "/letter_avatar_proxy/v4/letter/b/3be4f8/{size}.png",
|
||||
post_count: 1,
|
||||
primary_group_name: null,
|
||||
primary_group_flair_url: null,
|
||||
primary_group_flair_color: null,
|
||||
primary_group_flair_bg_color: null,
|
||||
flair_name: null,
|
||||
flair_url: null,
|
||||
flair_color: null,
|
||||
flair_bg_color: null,
|
||||
},
|
||||
],
|
||||
allowed_users: [
|
||||
|
@ -207,6 +209,7 @@ export default {
|
|||
grant_trust_level: null,
|
||||
incoming_email: null,
|
||||
has_messages: true,
|
||||
flair_name: null,
|
||||
flair_url: null,
|
||||
flair_bg_color: "",
|
||||
flair_color: "",
|
||||
|
@ -4217,9 +4220,10 @@ export default {
|
|||
topic_slug: "pm-for-testing",
|
||||
display_username: null,
|
||||
primary_group_name: null,
|
||||
primary_group_flair_url: null,
|
||||
primary_group_flair_bg_color: null,
|
||||
primary_group_flair_color: null,
|
||||
flair_name: null,
|
||||
flair_url: null,
|
||||
flair_bg_color: null,
|
||||
flair_color: null,
|
||||
version: 1,
|
||||
can_edit: true,
|
||||
can_delete: false,
|
||||
|
@ -4269,9 +4273,10 @@ export default {
|
|||
topic_slug: "pm-for-testing",
|
||||
display_username: null,
|
||||
primary_group_name: null,
|
||||
primary_group_flair_url: null,
|
||||
primary_group_flair_bg_color: null,
|
||||
primary_group_flair_color: null,
|
||||
flair_name: null,
|
||||
flair_url: null,
|
||||
flair_bg_color: null,
|
||||
flair_color: null,
|
||||
version: 1,
|
||||
can_edit: true,
|
||||
can_delete: true,
|
||||
|
@ -4363,6 +4368,7 @@ export default {
|
|||
grant_trust_level: null,
|
||||
incoming_email: null,
|
||||
has_messages: false,
|
||||
flair_name: null,
|
||||
flair_url: null,
|
||||
flair_bg_color: null,
|
||||
flair_color: null,
|
||||
|
@ -4384,9 +4390,10 @@ export default {
|
|||
avatar_template: "/images/avatar.png",
|
||||
post_count: 2,
|
||||
primary_group_name: null,
|
||||
primary_group_flair_url: null,
|
||||
primary_group_flair_color: null,
|
||||
primary_group_flair_bg_color: null,
|
||||
flair_name: null,
|
||||
flair_url: null,
|
||||
flair_color: null,
|
||||
flair_bg_color: null,
|
||||
},
|
||||
],
|
||||
suggested_topics: [
|
||||
|
@ -5064,9 +5071,10 @@ export default {
|
|||
topic_slug: "test-pm",
|
||||
display_username: null,
|
||||
primary_group_name: null,
|
||||
primary_group_flair_url: null,
|
||||
primary_group_flair_bg_color: null,
|
||||
primary_group_flair_color: null,
|
||||
flair_name: null,
|
||||
flair_url: null,
|
||||
flair_bg_color: null,
|
||||
flair_color: null,
|
||||
version: 1,
|
||||
can_edit: true,
|
||||
can_delete: false,
|
||||
|
@ -5126,9 +5134,10 @@ export default {
|
|||
topic_slug: "test-pm",
|
||||
display_username: "Tim Lange",
|
||||
primary_group_name: null,
|
||||
primary_group_flair_url: null,
|
||||
primary_group_flair_bg_color: null,
|
||||
primary_group_flair_color: null,
|
||||
flair_name: null,
|
||||
flair_url: null,
|
||||
flair_bg_color: null,
|
||||
flair_color: null,
|
||||
version: 1,
|
||||
can_edit: true,
|
||||
can_delete: true,
|
||||
|
@ -5237,9 +5246,10 @@ export default {
|
|||
avatar_template: "/images/avatar.png",
|
||||
post_count: 2,
|
||||
primary_group_name: null,
|
||||
primary_group_flair_url: null,
|
||||
primary_group_flair_color: null,
|
||||
primary_group_flair_bg_color: null,
|
||||
flair_name: null,
|
||||
flair_url: null,
|
||||
flair_color: null,
|
||||
flair_bg_color: null,
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
|
@ -5248,9 +5258,10 @@ export default {
|
|||
avatar_template: "/images/avatar.png",
|
||||
post_count: 1,
|
||||
primary_group_name: null,
|
||||
primary_group_flair_url: null,
|
||||
primary_group_flair_color: null,
|
||||
primary_group_flair_bg_color: null,
|
||||
flair_name: null,
|
||||
flair_url: null,
|
||||
flair_color: null,
|
||||
flair_bg_color: null,
|
||||
},
|
||||
],
|
||||
notification_level: 3,
|
||||
|
@ -5317,9 +5328,10 @@ export default {
|
|||
topic_slug: "a-topic-with-group-category-moderators",
|
||||
display_username: "",
|
||||
primary_group_name: "group_moderators",
|
||||
primary_group_flair_url: "cheese",
|
||||
primary_group_flair_bg_color: "ff0",
|
||||
primary_group_flair_color: "",
|
||||
flair_name: "group_moderators",
|
||||
flair_url: "cheese",
|
||||
flair_bg_color: "ff0",
|
||||
flair_color: "",
|
||||
version: 1,
|
||||
can_edit: true,
|
||||
can_delete: false,
|
||||
|
@ -5385,9 +5397,10 @@ export default {
|
|||
topic_slug: "a-topic-with-group-category-moderators",
|
||||
display_username: "",
|
||||
primary_group_name: null,
|
||||
primary_group_flair_url: null,
|
||||
primary_group_flair_bg_color: null,
|
||||
primary_group_flair_color: null,
|
||||
flair_name: null,
|
||||
flair_url: null,
|
||||
flair_bg_color: null,
|
||||
flair_color: null,
|
||||
version: 1,
|
||||
can_edit: false,
|
||||
can_delete: false,
|
||||
|
@ -5459,9 +5472,9 @@ export default {
|
|||
topic_slug: "a-topic-with-group-category-moderators",
|
||||
display_username: "",
|
||||
primary_group_name: "group_moderators",
|
||||
primary_group_flair_url: "cheese",
|
||||
primary_group_flair_bg_color: "ff0",
|
||||
primary_group_flair_color: "",
|
||||
flair_url: "cheese",
|
||||
flair_bg_color: "ff0",
|
||||
flair_color: "",
|
||||
version: 1,
|
||||
can_edit: true,
|
||||
can_delete: true,
|
||||
|
@ -5596,9 +5609,10 @@ export default {
|
|||
avatar_template: "/images/avatar.png",
|
||||
post_count: 2,
|
||||
primary_group_name: "group_moderators",
|
||||
primary_group_flair_url: "cheese",
|
||||
primary_group_flair_color: "",
|
||||
primary_group_flair_bg_color: "ff0",
|
||||
flar_name: "group_moderators",
|
||||
flair_url: "cheese",
|
||||
flair_color: "",
|
||||
flair_bg_color: "ff0",
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
|
@ -5607,9 +5621,10 @@ export default {
|
|||
avatar_template: "/images/avatar.png",
|
||||
post_count: 1,
|
||||
primary_group_name: null,
|
||||
primary_group_flair_url: null,
|
||||
primary_group_flair_color: null,
|
||||
primary_group_flair_bg_color: null,
|
||||
flair_name: null,
|
||||
flair_url: null,
|
||||
flair_color: null,
|
||||
flair_bg_color: null,
|
||||
},
|
||||
],
|
||||
created_by: {
|
||||
|
|
|
@ -2508,9 +2508,10 @@ export default {
|
|||
time_read: 0,
|
||||
recent_time_read: 0,
|
||||
primary_group_name: null,
|
||||
primary_group_flair_url: null,
|
||||
primary_group_flair_bg_color: null,
|
||||
primary_group_flair_color: null,
|
||||
flair_name: null,
|
||||
flair_url: null,
|
||||
flair_bg_color: null,
|
||||
flair_color: null,
|
||||
staged: false,
|
||||
second_factor_enabled: false,
|
||||
post_count: 0,
|
||||
|
@ -2755,9 +2756,10 @@ export default {
|
|||
time_read: 0,
|
||||
recent_time_read: 0,
|
||||
primary_group_name: null,
|
||||
primary_group_flair_url: null,
|
||||
primary_group_flair_bg_color: null,
|
||||
primary_group_flair_color: null,
|
||||
flair_name: null,
|
||||
flair_url: null,
|
||||
flair_bg_color: null,
|
||||
flair_color: null,
|
||||
staged: false,
|
||||
featured_user_badge_ids: [17],
|
||||
},
|
||||
|
@ -2870,9 +2872,10 @@ export default {
|
|||
time_read: 0,
|
||||
recent_time_read: 0,
|
||||
primary_group_name: null,
|
||||
primary_group_flair_url: null,
|
||||
primary_group_flair_bg_color: null,
|
||||
primary_group_flair_color: null,
|
||||
flair_name: null,
|
||||
flair_url: null,
|
||||
flair_bg_color: null,
|
||||
flair_color: null,
|
||||
second_factor_enabled: false,
|
||||
second_factor_backup_enabled: false,
|
||||
associated_accounts: [],
|
||||
|
|
|
@ -175,9 +175,10 @@ discourseModule(
|
|||
admin: false,
|
||||
moderator: false,
|
||||
trust_level: 3,
|
||||
primary_group_flair_url: "fa-times",
|
||||
primary_group_flair_bg_color: "123456",
|
||||
primary_group_flair_color: "B0B0B0",
|
||||
flair_name: "Band Geeks",
|
||||
flair_url: "fa-times",
|
||||
flair_bg_color: "123456",
|
||||
flair_color: "B0B0B0",
|
||||
primary_group_name: "Band Geeks",
|
||||
});
|
||||
setupSiteGroups(this);
|
||||
|
|
|
@ -17,9 +17,9 @@ discourseModule(
|
|||
template: hbs`{{mount-widget widget="avatar-flair" args=args}}`,
|
||||
beforeEach() {
|
||||
this.set("args", {
|
||||
primary_group_flair_url: "fa-bars",
|
||||
primary_group_flair_bg_color: "CC0000",
|
||||
primary_group_flair_color: "FFFFFF",
|
||||
flair_url: "fa-bars",
|
||||
flair_bg_color: "CC0000",
|
||||
flair_color: "FFFFFF",
|
||||
});
|
||||
},
|
||||
test(assert) {
|
||||
|
@ -37,7 +37,7 @@ discourseModule(
|
|||
template: hbs`{{mount-widget widget="avatar-flair" args=args}}`,
|
||||
beforeEach() {
|
||||
this.set("args", {
|
||||
primary_group_flair_url: "/images/avatar.png",
|
||||
flair_url: "/images/avatar.png",
|
||||
});
|
||||
},
|
||||
test(assert) {
|
||||
|
|
|
@ -39,8 +39,9 @@ discourseModule(
|
|||
avatar_template: "/images/avatar.png",
|
||||
post_count: 5,
|
||||
primary_group_name: "devs",
|
||||
primary_group_flair_url: "/images/d-logo-sketch-small.png",
|
||||
primary_group_flair_bg_color: "222",
|
||||
flair_name: "devs",
|
||||
flair_url: "/images/d-logo-sketch-small.png",
|
||||
flair_bg_color: "222",
|
||||
});
|
||||
},
|
||||
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
import ComboBoxComponent from "select-kit/components/combo-box";
|
||||
|
||||
export default ComboBoxComponent.extend({
|
||||
pluginApiIdentifiers: ["flair-chooser"],
|
||||
classNames: ["flair-chooser"],
|
||||
|
||||
selectKitOptions: {
|
||||
selectedNameComponent: "selected-flair",
|
||||
},
|
||||
|
||||
modifyComponentForRow() {
|
||||
return "flair-row";
|
||||
},
|
||||
});
|
|
@ -0,0 +1,7 @@
|
|||
import SelectKitRowComponent from "select-kit/components/select-kit/select-kit-row";
|
||||
import layout from "select-kit/templates/components/flair-row";
|
||||
|
||||
export default SelectKitRowComponent.extend({
|
||||
layout,
|
||||
classNames: ["flair-row"],
|
||||
});
|
|
@ -0,0 +1,7 @@
|
|||
import SelectedNameComponent from "select-kit/components/selected-name";
|
||||
import layout from "select-kit/templates/components/flair-row";
|
||||
|
||||
export default SelectedNameComponent.extend({
|
||||
layout,
|
||||
tagName: "",
|
||||
});
|
|
@ -0,0 +1,10 @@
|
|||
{{#if item.url}}
|
||||
{{avatar-flair
|
||||
flairName=item.name
|
||||
flairUrl=item.url
|
||||
flairBgColor=item.bgColor
|
||||
flairColor=item.color
|
||||
}}
|
||||
{{/if}}
|
||||
|
||||
<span>{{label}}</span>
|
|
@ -8,6 +8,7 @@
|
|||
@import "composer-actions";
|
||||
@import "dropdown-select-box";
|
||||
@import "email-group-user-chooser";
|
||||
@import "flair-row";
|
||||
@import "future-date-input-selector";
|
||||
@import "icon-picker";
|
||||
@import "list-setting";
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
.flair-chooser .select-kit-header,
|
||||
.select-kit .flair-row {
|
||||
.avatar-flair {
|
||||
align-items: center;
|
||||
background-position: center;
|
||||
background-repeat: no-repeat;
|
||||
background-size: 30px 30px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
margin-right: 5px;
|
||||
height: 30px;
|
||||
width: 30px;
|
||||
|
||||
&.rounded {
|
||||
background-size: (30px / 1.4) (30px / 1.4);
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.d-icon {
|
||||
display: block;
|
||||
height: (30px / 1.8);
|
||||
width: (30px / 1.8);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.select-kit.flair-chooser .select-kit-header {
|
||||
padding: 2px 4px;
|
||||
}
|
|
@ -61,7 +61,7 @@ class PostsController < ApplicationController
|
|||
.where('posts.id <= ?', last_post_id)
|
||||
.where('posts.id > ?', last_post_id - 50)
|
||||
.includes(topic: :category)
|
||||
.includes(user: :primary_group)
|
||||
.includes(user: [:primary_group, :flair_group])
|
||||
.includes(:reply_to_user)
|
||||
.limit(50)
|
||||
rss_description = I18n.t("rss_description.private_posts")
|
||||
|
@ -71,7 +71,7 @@ class PostsController < ApplicationController
|
|||
.where('posts.id <= ?', last_post_id)
|
||||
.where('posts.id > ?', last_post_id - 50)
|
||||
.includes(topic: :category)
|
||||
.includes(user: :primary_group)
|
||||
.includes(user: [:primary_group, :flair_group])
|
||||
.includes(:reply_to_user)
|
||||
.limit(50)
|
||||
rss_description = I18n.t("rss_description.posts")
|
||||
|
|
|
@ -10,7 +10,7 @@ class UserBadgesController < ApplicationController
|
|||
|
||||
badge = fetch_badge_from_params
|
||||
user_badges = badge.user_badges.order('granted_at DESC, id DESC').limit(MAX_BADGES)
|
||||
user_badges = user_badges.includes(:user, :granted_by, badge: :badge_type, post: :topic, user: :primary_group)
|
||||
user_badges = user_badges.includes(:user, :granted_by, badge: :badge_type, post: :topic, user: [:primary_group, :flair_group])
|
||||
|
||||
grant_count = nil
|
||||
|
||||
|
|
|
@ -112,6 +112,7 @@ class UsersController < ApplicationController
|
|||
:user_profile,
|
||||
:card_background_upload,
|
||||
:primary_group,
|
||||
:flair_group,
|
||||
:primary_email
|
||||
)
|
||||
|
||||
|
@ -1632,6 +1633,7 @@ class UsersController < ApplicationController
|
|||
:profile_background_upload_url,
|
||||
:card_background_upload_url,
|
||||
:primary_group_id,
|
||||
:flair_group_id,
|
||||
:featured_topic_id
|
||||
]
|
||||
|
||||
|
|
|
@ -33,6 +33,7 @@ class TopicPostersSummary
|
|||
topic_poster.user = user
|
||||
topic_poster.description = descriptions_for(user)
|
||||
topic_poster.primary_group = user_lookup.primary_groups[user.id]
|
||||
topic_poster.flair_group = user_lookup.flair_groups[user.id]
|
||||
if topic.last_post_user_id == user.id
|
||||
topic_poster.extras = +'latest'
|
||||
topic_poster.extras << ' single' if user_ids.uniq.size == 1
|
||||
|
|
|
@ -95,6 +95,7 @@ class User < ActiveRecord::Base
|
|||
has_one :card_background_upload, through: :user_profile
|
||||
belongs_to :approved_by, class_name: 'User'
|
||||
belongs_to :primary_group, class_name: 'Group'
|
||||
belongs_to :flair_group, class_name: 'Group'
|
||||
|
||||
has_many :muted_users, through: :muted_user_records
|
||||
has_many :ignored_users, through: :ignored_user_records
|
||||
|
@ -133,7 +134,7 @@ class User < ActiveRecord::Base
|
|||
|
||||
before_save :update_usernames
|
||||
before_save :ensure_password_is_hashed
|
||||
before_save :match_title_to_primary_group_changes
|
||||
before_save :match_primary_group_changes
|
||||
before_save :check_if_title_is_badged_granted
|
||||
|
||||
after_save :expire_tokens_if_password_changed
|
||||
|
@ -1619,12 +1620,16 @@ class User < ActiveRecord::Base
|
|||
end
|
||||
end
|
||||
|
||||
def match_title_to_primary_group_changes
|
||||
def match_primary_group_changes
|
||||
return unless primary_group_id_changed?
|
||||
|
||||
if title == Group.where(id: primary_group_id_was).pluck_first(:title)
|
||||
self.title = primary_group&.title
|
||||
end
|
||||
|
||||
if flair_group_id == primary_group_id_was
|
||||
self.flair_group_id = primary_group&.id
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
@ -1745,6 +1750,7 @@ end
|
|||
# group_locked_trust_level :integer
|
||||
# manual_locked_trust_level :integer
|
||||
# secure_identifier :string
|
||||
# flair_group_id :integer
|
||||
#
|
||||
# Indexes
|
||||
#
|
||||
|
|
|
@ -198,9 +198,14 @@ protected
|
|||
|
||||
if lookup_hash.present?
|
||||
primary_group = lookup.primary_groups[user_id]
|
||||
flair_group = lookup.flair_groups[user_id]
|
||||
|
||||
UserWithCount.new(
|
||||
lookup_hash.attributes.merge(count: user_hash[user_id], primary_group: primary_group)
|
||||
lookup_hash.attributes.merge(
|
||||
count: user_hash[user_id],
|
||||
primary_group: primary_group,
|
||||
flair_group: flair_group
|
||||
)
|
||||
)
|
||||
end
|
||||
end.compact.sort_by { |u| -u[:count] }
|
||||
|
|
|
@ -4,9 +4,10 @@ module UserPrimaryGroupMixin
|
|||
|
||||
def self.included(klass)
|
||||
klass.attributes :primary_group_name,
|
||||
:primary_group_flair_url,
|
||||
:primary_group_flair_bg_color,
|
||||
:primary_group_flair_color,
|
||||
:flair_name,
|
||||
:flair_url,
|
||||
:flair_bg_color,
|
||||
:flair_color,
|
||||
:admin,
|
||||
:moderator,
|
||||
:trust_level
|
||||
|
@ -20,28 +21,36 @@ module UserPrimaryGroupMixin
|
|||
object&.primary_group.present?
|
||||
end
|
||||
|
||||
def primary_group_flair_url
|
||||
object&.primary_group&.flair_url
|
||||
def flair_name
|
||||
object&.flair_group&.name
|
||||
end
|
||||
|
||||
def include_primary_group_flair_url?
|
||||
object&.primary_group&.flair_url.present?
|
||||
def include_flair_group_name?
|
||||
object&.flair_group.present?
|
||||
end
|
||||
|
||||
def primary_group_flair_bg_color
|
||||
object&.primary_group&.flair_bg_color
|
||||
def flair_url
|
||||
object&.flair_group&.flair_url
|
||||
end
|
||||
|
||||
def include_primary_group_flair_bg_color?
|
||||
object&.primary_group&.flair_bg_color.present?
|
||||
def include_flair_url?
|
||||
object&.flair_group&.flair_url.present?
|
||||
end
|
||||
|
||||
def primary_group_flair_color
|
||||
object&.primary_group&.flair_color
|
||||
def flair_bg_color
|
||||
object&.flair_group&.flair_bg_color
|
||||
end
|
||||
|
||||
def include_primary_group_flair_color?
|
||||
object&.primary_group&.flair_color.present?
|
||||
def include_flair_bg_color?
|
||||
object&.flair_group&.flair_bg_color.present?
|
||||
end
|
||||
|
||||
def flair_color
|
||||
object&.flair_group&.flair_color
|
||||
end
|
||||
|
||||
def include_flair_color?
|
||||
object&.flair_group&.flair_color.present?
|
||||
end
|
||||
|
||||
def include_admin?
|
||||
|
|
|
@ -48,6 +48,7 @@ class CurrentUserSerializer < BasicUserSerializer
|
|||
:previous_visit_at,
|
||||
:seen_notification_id,
|
||||
:primary_group_id,
|
||||
:flair_group_id,
|
||||
:can_create_topic,
|
||||
:can_create_group,
|
||||
:link_posting_access,
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class FlairGroupSerializer < ApplicationSerializer
|
||||
attributes :id, :name, :flair_url, :flair_bg_color, :flair_color
|
||||
end
|
|
@ -36,9 +36,10 @@ class PostSerializer < BasicPostSerializer
|
|||
:category_id,
|
||||
:display_username,
|
||||
:primary_group_name,
|
||||
:primary_group_flair_url,
|
||||
:primary_group_flair_bg_color,
|
||||
:primary_group_flair_color,
|
||||
:flair_name,
|
||||
:flair_url,
|
||||
:flair_bg_color,
|
||||
:flair_color,
|
||||
:version,
|
||||
:can_edit,
|
||||
:can_delete,
|
||||
|
@ -188,16 +189,20 @@ class PostSerializer < BasicPostSerializer
|
|||
end
|
||||
end
|
||||
|
||||
def primary_group_flair_url
|
||||
object.user&.primary_group&.flair_url
|
||||
def flair_name
|
||||
object.user&.flair_group&.name
|
||||
end
|
||||
|
||||
def primary_group_flair_bg_color
|
||||
object.user&.primary_group&.flair_bg_color
|
||||
def flair_url
|
||||
object.user&.flair_group&.flair_url
|
||||
end
|
||||
|
||||
def primary_group_flair_color
|
||||
object.user&.primary_group&.flair_color
|
||||
def flair_bg_color
|
||||
object.user&.flair_group&.flair_bg_color
|
||||
end
|
||||
|
||||
def flair_color
|
||||
object.user&.flair_group&.flair_color
|
||||
end
|
||||
|
||||
def link_counts
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class PrimaryGroupSerializer < ApplicationSerializer
|
||||
attributes :id, :name, :flair_url, :flair_bg_color, :flair_color
|
||||
attributes :id, :name
|
||||
end
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
class TopicPostCountSerializer < BasicUserSerializer
|
||||
|
||||
attributes :post_count, :primary_group_name,
|
||||
:primary_group_flair_url, :primary_group_flair_color, :primary_group_flair_bg_color,
|
||||
:flair_name, :flair_url, :flair_color, :flair_bg_color,
|
||||
:admin, :moderator, :trust_level,
|
||||
|
||||
def id
|
||||
|
@ -23,16 +23,20 @@ class TopicPostCountSerializer < BasicUserSerializer
|
|||
object[:user]&.primary_group&.name
|
||||
end
|
||||
|
||||
def primary_group_flair_url
|
||||
object[:user]&.primary_group&.flair_url
|
||||
def flair_name
|
||||
object[:user]&.flair_group&.name
|
||||
end
|
||||
|
||||
def primary_group_flair_bg_color
|
||||
object[:user]&.primary_group&.flair_bg_color
|
||||
def flair_url
|
||||
object[:user]&.flair_group&.flair_url
|
||||
end
|
||||
|
||||
def primary_group_flair_color
|
||||
object[:user]&.primary_group&.flair_color
|
||||
def flair_bg_color
|
||||
object[:user]&.flair_group&.flair_bg_color
|
||||
end
|
||||
|
||||
def flair_color
|
||||
object[:user]&.flair_group&.flair_color
|
||||
end
|
||||
|
||||
def include_admin?
|
||||
|
|
|
@ -5,4 +5,5 @@ class TopicPosterSerializer < ApplicationSerializer
|
|||
|
||||
has_one :user, serializer: PosterSerializer
|
||||
has_one :primary_group, serializer: PrimaryGroupSerializer
|
||||
has_one :flair_group, serializer: FlairGroupSerializer
|
||||
end
|
||||
|
|
|
@ -59,9 +59,10 @@ class UserCardSerializer < BasicUserSerializer
|
|||
:recent_time_read,
|
||||
:primary_group_id,
|
||||
:primary_group_name,
|
||||
:primary_group_flair_url,
|
||||
:primary_group_flair_bg_color,
|
||||
:primary_group_flair_color,
|
||||
:flair_name,
|
||||
:flair_url,
|
||||
:flair_bg_color,
|
||||
:flair_color,
|
||||
:featured_topic,
|
||||
:timezone
|
||||
|
||||
|
@ -181,19 +182,23 @@ class UserCardSerializer < BasicUserSerializer
|
|||
end
|
||||
|
||||
def primary_group_name
|
||||
object.primary_group.try(:name)
|
||||
object.primary_group&.name
|
||||
end
|
||||
|
||||
def primary_group_flair_url
|
||||
object.try(:primary_group).try(:flair_url)
|
||||
def flair_name
|
||||
object.flair_group&.name
|
||||
end
|
||||
|
||||
def primary_group_flair_bg_color
|
||||
object.try(:primary_group).try(:flair_bg_color)
|
||||
def flair_url
|
||||
object.flair_group&.flair_url
|
||||
end
|
||||
|
||||
def primary_group_flair_color
|
||||
object.try(:primary_group).try(:flair_color)
|
||||
def flair_bg_color
|
||||
object.flair_group&.flair_bg_color
|
||||
end
|
||||
|
||||
def flair_color
|
||||
object.flair_group&.flair_color
|
||||
end
|
||||
|
||||
def featured_topic
|
||||
|
|
|
@ -29,9 +29,10 @@ class UserSummarySerializer < ApplicationSerializer
|
|||
:admin,
|
||||
:moderator,
|
||||
:trust_level,
|
||||
:primary_group_flair_url,
|
||||
:primary_group_flair_bg_color,
|
||||
:primary_group_flair_color,
|
||||
:flair_name,
|
||||
:flair_url,
|
||||
:flair_bg_color,
|
||||
:flair_color,
|
||||
:primary_group_name
|
||||
|
||||
def include_name?
|
||||
|
@ -42,16 +43,20 @@ class UserSummarySerializer < ApplicationSerializer
|
|||
User.avatar_template(object[:username], object[:uploaded_avatar_id])
|
||||
end
|
||||
|
||||
def primary_group_flair_url
|
||||
object.primary_group&.flair_url
|
||||
def flair_name
|
||||
object.flair_group&.name
|
||||
end
|
||||
|
||||
def primary_group_flair_bg_color
|
||||
object.primary_group&.flair_bg_color
|
||||
def flair_url
|
||||
object.flair_group&.flair_url
|
||||
end
|
||||
|
||||
def primary_group_flair_color
|
||||
object.primary_group&.flair_color
|
||||
def flair_bg_color
|
||||
object.flair_group&.flair_bg_color
|
||||
end
|
||||
|
||||
def flair_color
|
||||
object.flair_group&.flair_color
|
||||
end
|
||||
|
||||
def primary_group_name
|
||||
|
|
|
@ -28,9 +28,9 @@ class WebHookPostSerializer < PostSerializer
|
|||
actions_summary
|
||||
can_view_edit_history
|
||||
yours
|
||||
primary_group_flair_url
|
||||
primary_group_flair_bg_color
|
||||
primary_group_flair_color
|
||||
flair_url
|
||||
flair_bg_color
|
||||
flair_color
|
||||
notice
|
||||
}.each do |attr|
|
||||
define_method("include_#{attr}?") do
|
||||
|
|
|
@ -121,6 +121,13 @@ class UserUpdater
|
|||
user.primary_group_id = nil
|
||||
end
|
||||
|
||||
if attributes[:flair_group_id] &&
|
||||
attributes[:flair_group_id] != user.flair_group_id &&
|
||||
guardian.can_use_primary_group?(user, attributes[:flair_group_id])
|
||||
|
||||
user.flair_group_id = attributes[:flair_group_id]
|
||||
end
|
||||
|
||||
CATEGORY_IDS.each do |attribute, level|
|
||||
if ids = attributes[attribute]
|
||||
CategoryUser.batch_set(user, level, ids)
|
||||
|
|
|
@ -1646,6 +1646,11 @@ en:
|
|||
title:
|
||||
title: "Title"
|
||||
none: "(none)"
|
||||
instructions: "appears after your username"
|
||||
flair:
|
||||
title: "Flair"
|
||||
none: "(none)"
|
||||
instructions: "icon displayed next to your profile picture"
|
||||
primary_group:
|
||||
title: "Primary Group"
|
||||
none: "(none)"
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class AddFlairGroupIdToUsers < ActiveRecord::Migration[6.1]
|
||||
def change
|
||||
add_column :users, :flair_group_id, :integer, null: true
|
||||
end
|
||||
end
|
|
@ -12,13 +12,33 @@ class UserLookup
|
|||
end
|
||||
|
||||
def primary_groups
|
||||
@groups ||= group_lookup_hash
|
||||
@primary_groups ||= begin
|
||||
hash = {}
|
||||
users.values.each do |u|
|
||||
if u.primary_group_id
|
||||
hash[u.id] = groups[u.primary_group_id]
|
||||
end
|
||||
end
|
||||
hash
|
||||
end
|
||||
end
|
||||
|
||||
def flair_groups
|
||||
@flair_groups ||= begin
|
||||
hash = {}
|
||||
users.values.each do |u|
|
||||
if u.flair_group_id
|
||||
hash[u.id] = groups[u.flair_group_id]
|
||||
end
|
||||
end
|
||||
hash
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def self.lookup_columns
|
||||
@user_lookup_columns ||= %i{id username name uploaded_avatar_id primary_group_id admin moderator trust_level}
|
||||
@user_lookup_columns ||= %i{id username name uploaded_avatar_id primary_group_id flair_group_id admin moderator trust_level}
|
||||
end
|
||||
|
||||
def self.group_lookup_columns
|
||||
|
@ -37,23 +57,21 @@ class UserLookup
|
|||
hash
|
||||
end
|
||||
|
||||
def group_lookup_hash
|
||||
users_with_primary_group = users.values.reject { |u| u.primary_group_id.nil? }
|
||||
def groups
|
||||
@group_lookup = begin
|
||||
group_ids = users.values.map { |u| [u.primary_group_id, u.flair_group_id] }
|
||||
group_ids.flatten!
|
||||
group_ids.uniq!
|
||||
group_ids.compact!
|
||||
|
||||
group_lookup = {}
|
||||
group_ids = users_with_primary_group.map { |u| u.primary_group_id }
|
||||
group_ids.uniq!
|
||||
hash = {}
|
||||
|
||||
Group.includes(:flair_upload)
|
||||
.where(id: group_ids)
|
||||
.select(self.class.group_lookup_columns)
|
||||
.each { |g| group_lookup[g.id] = g }
|
||||
Group.includes(:flair_upload)
|
||||
.where(id: group_ids)
|
||||
.select(self.class.group_lookup_columns)
|
||||
.each { |g| hash[g.id] = g }
|
||||
|
||||
hash = {}
|
||||
users_with_primary_group.each do |u|
|
||||
hash[u.id] = group_lookup[u.primary_group_id]
|
||||
hash
|
||||
end
|
||||
hash
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -38,9 +38,9 @@ acceptance("Poll in a post reply history", function (needs) {
|
|||
topic_slug: "topic-with-a-poll-in-a-post-reply-history",
|
||||
display_username: null,
|
||||
primary_group_name: null,
|
||||
primary_group_flair_url: null,
|
||||
primary_group_flair_bg_color: null,
|
||||
primary_group_flair_color: null,
|
||||
flair_url: null,
|
||||
flair_bg_color: null,
|
||||
flair_color: null,
|
||||
version: 1,
|
||||
can_edit: true,
|
||||
can_delete: true,
|
||||
|
@ -337,9 +337,9 @@ acceptance("Poll in a post reply history", function (needs) {
|
|||
"/letter_avatar_proxy/v4/letter/a/bbce88/{size}.png",
|
||||
post_count: 4,
|
||||
primary_group_name: null,
|
||||
primary_group_flair_url: null,
|
||||
primary_group_flair_color: null,
|
||||
primary_group_flair_bg_color: null,
|
||||
flair_url: null,
|
||||
flair_color: null,
|
||||
flair_bg_color: null,
|
||||
},
|
||||
],
|
||||
created_by: {
|
||||
|
@ -385,9 +385,9 @@ acceptance("Poll in a post reply history", function (needs) {
|
|||
topic_slug: "topic-with-a-poll-in-a-post-reply-history",
|
||||
display_username: null,
|
||||
primary_group_name: null,
|
||||
primary_group_flair_url: null,
|
||||
primary_group_flair_bg_color: null,
|
||||
primary_group_flair_color: null,
|
||||
flair_url: null,
|
||||
flair_bg_color: null,
|
||||
flair_color: null,
|
||||
version: 1,
|
||||
can_edit: false,
|
||||
can_delete: false,
|
||||
|
|
|
@ -35,9 +35,9 @@ acceptance("Poll quote", function (needs) {
|
|||
topic_slug: "topic-with-two-polls",
|
||||
display_username: null,
|
||||
primary_group_name: null,
|
||||
primary_group_flair_url: null,
|
||||
primary_group_flair_bg_color: null,
|
||||
primary_group_flair_color: null,
|
||||
flair_url: null,
|
||||
flair_bg_color: null,
|
||||
flair_color: null,
|
||||
version: 1,
|
||||
can_edit: true,
|
||||
can_delete: false,
|
||||
|
@ -154,9 +154,9 @@ acceptance("Poll quote", function (needs) {
|
|||
topic_slug: "topic-with-two-quoted-polls",
|
||||
display_username: null,
|
||||
primary_group_name: null,
|
||||
primary_group_flair_url: null,
|
||||
primary_group_flair_bg_color: null,
|
||||
primary_group_flair_color: null,
|
||||
flair_url: null,
|
||||
flair_bg_color: null,
|
||||
flair_color: null,
|
||||
version: 1,
|
||||
can_edit: true,
|
||||
can_delete: false,
|
||||
|
@ -399,9 +399,9 @@ acceptance("Poll quote", function (needs) {
|
|||
"/letter_avatar_proxy/v4/letter/b/3be4f8/{size}.png",
|
||||
post_count: 1,
|
||||
primary_group_name: null,
|
||||
primary_group_flair_url: null,
|
||||
primary_group_flair_color: null,
|
||||
primary_group_flair_bg_color: null,
|
||||
flair_url: null,
|
||||
flair_color: null,
|
||||
flair_bg_color: null,
|
||||
},
|
||||
],
|
||||
created_by: {
|
||||
|
|
|
@ -38,9 +38,9 @@ acceptance("Poll results", function (needs) {
|
|||
topic_slug: "load-more-poll-voters",
|
||||
display_username: null,
|
||||
primary_group_name: null,
|
||||
primary_group_flair_url: null,
|
||||
primary_group_flair_bg_color: null,
|
||||
primary_group_flair_color: null,
|
||||
flair_url: null,
|
||||
flair_bg_color: null,
|
||||
flair_color: null,
|
||||
version: 1,
|
||||
can_edit: true,
|
||||
can_delete: false,
|
||||
|
@ -143,9 +143,9 @@ acceptance("Poll results", function (needs) {
|
|||
topic_slug: "load-more-poll-voters",
|
||||
display_username: null,
|
||||
primary_group_name: null,
|
||||
primary_group_flair_url: null,
|
||||
primary_group_flair_bg_color: null,
|
||||
primary_group_flair_color: null,
|
||||
flair_url: null,
|
||||
flair_bg_color: null,
|
||||
flair_color: null,
|
||||
version: 1,
|
||||
can_edit: true,
|
||||
can_delete: false,
|
||||
|
@ -499,9 +499,9 @@ acceptance("Poll results", function (needs) {
|
|||
"/letter_avatar_proxy/v4/letter/b/3be4f8/{size}.png",
|
||||
post_count: 1,
|
||||
primary_group_name: null,
|
||||
primary_group_flair_url: null,
|
||||
primary_group_flair_color: null,
|
||||
primary_group_flair_bg_color: null,
|
||||
flair_url: null,
|
||||
flair_color: null,
|
||||
flair_bg_color: null,
|
||||
admin: true,
|
||||
trust_level: 0,
|
||||
},
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -2142,16 +2142,24 @@ describe User do
|
|||
|
||||
end
|
||||
|
||||
describe '#match_title_to_primary_group_changes' do
|
||||
let(:primary_group_a) { Fabricate(:group, title: 'A', users: [user]) }
|
||||
let(:primary_group_b) { Fabricate(:group, title: 'B', users: [user]) }
|
||||
describe '#match_primary_group_changes' do
|
||||
let(:group_a) { Fabricate(:group, title: 'A', users: [user]) }
|
||||
let(:group_b) { Fabricate(:group, title: 'B', users: [user]) }
|
||||
|
||||
it "updates user's title only when it is blank or matches the previous primary group" do
|
||||
expect { user.update(primary_group: primary_group_a) }.to change { user.reload.title }.from(nil).to('A')
|
||||
expect { user.update(primary_group: primary_group_b) }.to change { user.reload.title }.from('A').to('B')
|
||||
expect { user.update(primary_group: group_a) }.to change { user.reload.title }.from(nil).to('A')
|
||||
expect { user.update(primary_group: group_b) }.to change { user.reload.title }.from('A').to('B')
|
||||
|
||||
user.update(title: 'Different')
|
||||
expect { user.update(primary_group: primary_group_a) }.to_not change { user.reload.title }
|
||||
expect { user.update(primary_group: group_a) }.to_not change { user.reload.title }
|
||||
end
|
||||
|
||||
it "updates user's title only when it is blank or matches the previous primary group" do
|
||||
expect { user.update(primary_group: group_a) }.to change { user.reload.flair_group }.from(nil).to(group_a)
|
||||
expect { user.update(primary_group: group_b) }.to change { user.reload.flair_group }.from(group_a).to(group_b)
|
||||
|
||||
user.update(flair_group: group_a)
|
||||
expect { user.update(primary_group: group_a) }.to_not change { user.reload.flair_group }
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -51,9 +51,10 @@ describe 'posts' do
|
|||
category_id: { type: :integer },
|
||||
display_username: { type: :string },
|
||||
primary_group_name: { type: :string, nullable: true },
|
||||
primary_group_flair_url: { type: :string, nullable: true },
|
||||
primary_group_flair_bg_color: { type: :string, nullable: true },
|
||||
primary_group_flair_color: { type: :string, nullable: true },
|
||||
flair_name: { type: :string, nullable: true },
|
||||
flair_url: { type: :string, nullable: true },
|
||||
flair_bg_color: { type: :string, nullable: true },
|
||||
flair_color: { type: :string, nullable: true },
|
||||
version: { type: :integer },
|
||||
can_edit: { type: :boolean },
|
||||
can_delete: { type: :boolean },
|
||||
|
@ -149,9 +150,10 @@ describe 'posts' do
|
|||
topic_slug: { type: :string },
|
||||
display_username: { type: :string, nullable: true },
|
||||
primary_group_name: { type: :string, nullable: true },
|
||||
primary_group_flair_url: { type: :string, nullable: true },
|
||||
primary_group_flair_bg_color: { type: :string, nullable: true },
|
||||
primary_group_flair_color: { type: :string, nullable: true },
|
||||
flair_name: { type: :string, nullable: true },
|
||||
flair_url: { type: :string, nullable: true },
|
||||
flair_bg_color: { type: :string, nullable: true },
|
||||
flair_color: { type: :string, nullable: true },
|
||||
version: { type: :integer },
|
||||
can_edit: { type: :boolean },
|
||||
can_delete: { type: :boolean },
|
||||
|
@ -237,9 +239,9 @@ describe 'posts' do
|
|||
topic_slug: { type: :string },
|
||||
display_username: { type: :string, nullable: true },
|
||||
primary_group_name: { type: :string, nullable: true },
|
||||
primary_group_flair_url: { type: :string, nullable: true },
|
||||
primary_group_flair_bg_color: { type: :string, nullable: true },
|
||||
primary_group_flair_color: { type: :string, nullable: true },
|
||||
flair_url: { type: :string, nullable: true },
|
||||
flair_bg_color: { type: :string, nullable: true },
|
||||
flair_color: { type: :string, nullable: true },
|
||||
version: { type: :integer },
|
||||
can_edit: { type: :boolean },
|
||||
can_delete: { type: :boolean },
|
||||
|
@ -359,9 +361,10 @@ describe 'posts' do
|
|||
topic_slug: { type: :string },
|
||||
display_username: { type: :string },
|
||||
primary_group_name: { type: :string, nullable: true },
|
||||
primary_group_flair_url: { type: :string, nullable: true },
|
||||
primary_group_flair_bg_color: { type: :string, nullable: true },
|
||||
primary_group_flair_color: { type: :string, nullable: true },
|
||||
flair_name: { type: :string, nullable: true },
|
||||
flair_url: { type: :string, nullable: true },
|
||||
flair_bg_color: { type: :string, nullable: true },
|
||||
flair_color: { type: :string, nullable: true },
|
||||
version: { type: :integer },
|
||||
can_edit: { type: :boolean },
|
||||
can_delete: { type: :boolean },
|
||||
|
|
|
@ -79,19 +79,25 @@
|
|||
"null"
|
||||
]
|
||||
},
|
||||
"primary_group_flair_url": {
|
||||
"flair_name": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"primary_group_flair_bg_color": {
|
||||
"flair_url": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"primary_group_flair_color": {
|
||||
"flair_bg_color": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"flair_color": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
|
@ -219,9 +225,10 @@
|
|||
"topic_slug",
|
||||
"display_username",
|
||||
"primary_group_name",
|
||||
"primary_group_flair_url",
|
||||
"primary_group_flair_bg_color",
|
||||
"primary_group_flair_color",
|
||||
"flair_name",
|
||||
"flair_url",
|
||||
"flair_bg_color",
|
||||
"flair_color",
|
||||
"version",
|
||||
"can_edit",
|
||||
"can_delete",
|
||||
|
|
|
@ -53,9 +53,10 @@ describe 'topics' do
|
|||
topic_slug: { type: :string },
|
||||
display_username: { type: :string, nullable: true },
|
||||
primary_group_name: { type: :string, nullable: true },
|
||||
primary_group_flair_url: { type: :string, nullable: true },
|
||||
primary_group_flair_bg_color: { type: :string, nullable: true },
|
||||
primary_group_flair_color: { type: :string, nullable: true },
|
||||
flair_name: { type: :string, nullable: true },
|
||||
flair_url: { type: :string, nullable: true },
|
||||
flair_bg_color: { type: :string, nullable: true },
|
||||
flair_color: { type: :string, nullable: true },
|
||||
version: { type: :integer },
|
||||
can_edit: { type: :boolean },
|
||||
can_delete: { type: :boolean },
|
||||
|
@ -144,9 +145,10 @@ describe 'topics' do
|
|||
topic_slug: { type: :string },
|
||||
display_username: { type: :string },
|
||||
primary_group_name: { type: :string, nullable: true },
|
||||
primary_group_flair_url: { type: :string, nullable: true },
|
||||
primary_group_flair_bg_color: { type: :string, nullable: true },
|
||||
primary_group_flair_color: { type: :string, nullable: true },
|
||||
flair_name: { type: :string, nullable: true },
|
||||
flair_url: { type: :string, nullable: true },
|
||||
flair_bg_color: { type: :string, nullable: true },
|
||||
flair_color: { type: :string, nullable: true },
|
||||
version: { type: :integer },
|
||||
can_edit: { type: :boolean },
|
||||
can_delete: { type: :boolean },
|
||||
|
@ -337,9 +339,10 @@ describe 'topics' do
|
|||
avatar_template: { type: :string },
|
||||
post_count: { type: :integer },
|
||||
primary_group_name: { type: :string, nullable: true },
|
||||
primary_group_flair_url: { type: :string, nullable: true },
|
||||
primary_group_flair_color: { type: :string, nullable: true },
|
||||
primary_group_flair_bg_color: { type: :string, nullable: true },
|
||||
flair_name: { type: :string, nullable: true },
|
||||
flair_url: { type: :string, nullable: true },
|
||||
flair_color: { type: :string, nullable: true },
|
||||
flair_bg_color: { type: :string, nullable: true },
|
||||
}
|
||||
},
|
||||
},
|
||||
|
|
|
@ -3098,32 +3098,32 @@ describe UsersController do
|
|||
expect(json["user_summary"]["most_liked_by_users"][0]["trust_level"]).to eq(1)
|
||||
end
|
||||
|
||||
it "returns data for primary group flair when an icon is used for flair" do
|
||||
it "returns data for flair when an icon is used" do
|
||||
group = Fabricate(:group, name: "Groupie", flair_bg_color: "#111111", flair_color: "#999999", flair_icon: "icon")
|
||||
liker = Fabricate(:user, primary_group: group)
|
||||
liker = Fabricate(:user, flair_group: group)
|
||||
create_and_like_post(user, liker)
|
||||
|
||||
get "/u/#{user.username_lower}/summary.json"
|
||||
json = response.parsed_body
|
||||
|
||||
expect(json["user_summary"]["most_liked_by_users"][0]["primary_group_flair_url"]).to eq("icon")
|
||||
expect(json["user_summary"]["most_liked_by_users"][0]["primary_group_name"]).to eq("Groupie")
|
||||
expect(json["user_summary"]["most_liked_by_users"][0]["primary_group_flair_bg_color"]).to eq("#111111")
|
||||
expect(json["user_summary"]["most_liked_by_users"][0]["primary_group_flair_color"]).to eq("#999999")
|
||||
expect(json["user_summary"]["most_liked_by_users"][0]["flair_name"]).to eq("Groupie")
|
||||
expect(json["user_summary"]["most_liked_by_users"][0]["flair_url"]).to eq("icon")
|
||||
expect(json["user_summary"]["most_liked_by_users"][0]["flair_bg_color"]).to eq("#111111")
|
||||
expect(json["user_summary"]["most_liked_by_users"][0]["flair_color"]).to eq("#999999")
|
||||
end
|
||||
|
||||
it "returns data for primary group flair when an image is used for flair" do
|
||||
it "returns data for flair when an image is used" do
|
||||
upload = Fabricate(:upload)
|
||||
group = Fabricate(:group, name: "Groupie", flair_bg_color: "#111111", flair_upload: upload)
|
||||
liker = Fabricate(:user, primary_group: group)
|
||||
liker = Fabricate(:user, flair_group: group)
|
||||
create_and_like_post(user, liker)
|
||||
|
||||
get "/u/#{user.username_lower}/summary.json"
|
||||
json = response.parsed_body
|
||||
|
||||
expect(json["user_summary"]["most_liked_by_users"][0]["primary_group_flair_url"]).to eq(upload.url)
|
||||
expect(json["user_summary"]["most_liked_by_users"][0]["primary_group_name"]).to eq("Groupie")
|
||||
expect(json["user_summary"]["most_liked_by_users"][0]["primary_group_flair_bg_color"]).to eq("#111111")
|
||||
expect(json["user_summary"]["most_liked_by_users"][0]["flair_name"]).to eq("Groupie")
|
||||
expect(json["user_summary"]["most_liked_by_users"][0]["flair_url"]).to eq(upload.url)
|
||||
expect(json["user_summary"]["most_liked_by_users"][0]["flair_bg_color"]).to eq("#111111")
|
||||
end
|
||||
|
||||
def create_and_like_post(likee, liker)
|
||||
|
|
|
@ -11,20 +11,51 @@ RSpec.describe WebHookPostSerializer do
|
|||
end
|
||||
|
||||
it 'should only include the required keys' do
|
||||
count = serialized_for_user(admin).keys.count
|
||||
difference = count - 42
|
||||
|
||||
expect(difference).to eq(0), lambda {
|
||||
message = +""
|
||||
|
||||
if difference < 0
|
||||
message << "#{difference * -1} key(s) have been removed from this serializer."
|
||||
else
|
||||
message << "#{difference} key(s) have been added to this serializer."
|
||||
end
|
||||
|
||||
message << "\nPlease verify if those key(s) are required as part of the web hook's payload."
|
||||
}
|
||||
expect(serialized_for_user(admin).keys).to contain_exactly(
|
||||
:id,
|
||||
:name,
|
||||
:username,
|
||||
:avatar_template,
|
||||
:created_at,
|
||||
:cooked,
|
||||
:post_number,
|
||||
:post_type,
|
||||
:updated_at,
|
||||
:reply_count,
|
||||
:reply_to_post_number,
|
||||
:quote_count,
|
||||
:incoming_link_count,
|
||||
:reads,
|
||||
:score,
|
||||
:topic_id,
|
||||
:topic_slug,
|
||||
:topic_title,
|
||||
:category_id,
|
||||
:display_username,
|
||||
:primary_group_name,
|
||||
:flair_name,
|
||||
:version,
|
||||
:user_title,
|
||||
:bookmarked,
|
||||
:raw,
|
||||
:moderator,
|
||||
:admin,
|
||||
:staff,
|
||||
:user_id,
|
||||
:hidden,
|
||||
:trust_level,
|
||||
:deleted_at,
|
||||
:user_deleted,
|
||||
:edit_reason,
|
||||
:wiki,
|
||||
:reviewable_id,
|
||||
:reviewable_score_count,
|
||||
:reviewable_score_pending_count,
|
||||
:topic_posts_count,
|
||||
:topic_filtered_posts_count,
|
||||
:topic_archetype,
|
||||
:category_slug
|
||||
)
|
||||
end
|
||||
|
||||
it "includes category_id" do
|
||||
|
|
|
@ -22,14 +22,59 @@ RSpec.describe WebHookUserSerializer do
|
|||
end
|
||||
|
||||
it 'should only include the required keys' do
|
||||
count = serializer.as_json.keys.count
|
||||
difference = count - 51
|
||||
|
||||
expect(difference).to eq(0), lambda {
|
||||
message = (difference < 0 ?
|
||||
"#{difference * -1} key(s) have been removed from this serializer." :
|
||||
"#{difference} key(s) have been added to this serializer.") +
|
||||
"\nPlease verify if those key(s) are required as part of the web hook's payload."
|
||||
}
|
||||
expect(serializer.as_json.keys).to contain_exactly(
|
||||
:id,
|
||||
:username,
|
||||
:name,
|
||||
:avatar_template,
|
||||
:email,
|
||||
:secondary_emails,
|
||||
:last_posted_at,
|
||||
:last_seen_at,
|
||||
:created_at,
|
||||
:muted,
|
||||
:trust_level,
|
||||
:moderator,
|
||||
:admin,
|
||||
:title,
|
||||
:badge_count,
|
||||
:time_read,
|
||||
:recent_time_read,
|
||||
:primary_group_id,
|
||||
:primary_group_name,
|
||||
:flair_name,
|
||||
:flair_url,
|
||||
:flair_bg_color,
|
||||
:flair_color,
|
||||
:featured_topic,
|
||||
:staged,
|
||||
:pending_count,
|
||||
:profile_view_count,
|
||||
:second_factor_enabled,
|
||||
:can_upload_profile_header,
|
||||
:can_upload_user_card_background,
|
||||
:post_count,
|
||||
:locale,
|
||||
:muted_category_ids,
|
||||
:regular_category_ids,
|
||||
:watched_tags,
|
||||
:watching_first_post_tags,
|
||||
:tracked_tags,
|
||||
:muted_tags,
|
||||
:tracked_category_ids,
|
||||
:watched_category_ids,
|
||||
:watched_first_post_category_ids,
|
||||
:system_avatar_template,
|
||||
:muted_usernames,
|
||||
:ignored_usernames,
|
||||
:allowed_pm_usernames,
|
||||
:mailing_list_posts_per_day,
|
||||
:user_notification_schedule,
|
||||
:external_id,
|
||||
:featured_user_badge_ids,
|
||||
:invited_by,
|
||||
:groups,
|
||||
:user_option
|
||||
)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -153,9 +153,9 @@ RSpec.configure do |config|
|
|||
recent_time_read: { type: :integer },
|
||||
primary_group_id: { type: :string, nullable: true },
|
||||
primary_group_name: { type: :string, nullable: true },
|
||||
primary_group_flair_url: { type: :string, nullable: true },
|
||||
primary_group_flair_bg_color: { type: :string, nullable: true },
|
||||
primary_group_flair_color: { type: :string, nullable: true },
|
||||
flair_url: { type: :string, nullable: true },
|
||||
flair_bg_color: { type: :string, nullable: true },
|
||||
flair_color: { type: :string, nullable: true },
|
||||
featured_topic: { type: :string, nullable: true },
|
||||
staged: { type: :boolean },
|
||||
can_edit: { type: :boolean },
|
||||
|
|
Loading…
Reference in New Issue