FEATURE: Allow setting avatar flair for automatic groups (#12586)

FEATURE: Allow setting avatar flair for automatic groups (#12586)

diff --git a/app/assets/javascripts/discourse/app/components/user-avatar-flair.js b/app/assets/javascripts/discourse/app/components/user-avatar-flair.js
new file mode 100644
index 0000000..21464ba
--- /dev/null
+++ b/app/assets/javascripts/discourse/app/components/user-avatar-flair.js
@@ -0,0 +1,38 @@
+import MountWidget from "discourse/components/mount-widget";
+import { observes } from "discourse-common/utils/decorators";
+import autoGroupFlairForUser from "discourse/lib/avatar-flair";
+
+export default MountWidget.extend({
+  widget: "avatar-flair",
+
+  @observes("user")
+  _rerender() {
+    this.queueRerender();
+  },
+
+  buildArgs() {
+    if (!this.user) {
+      return;
+    }
+
+    if (this.user.primary_group_flair_url) {
+      return {
+        primary_group_flair_url: this.user.primary_group_flair_url,
+        primary_group_flair_bg_color: this.user.primary_group_flair_bg_color,
+        primary_group_flair_color: this.user.primary_group_flair_color,
+        primary_group_name: this.user.primary_group_name,
+      };
+    } else {
+      const autoFlairAttrs = autoGroupFlairForUser(this.site, this.user);
+      if (autoFlairAttrs) {
+        return {
+          primary_group_flair_url: autoFlairAttrs.primary_group_flair_url,
+          primary_group_flair_bg_color:
+            autoFlairAttrs.primary_group_flair_bg_color,
+          primary_group_flair_color: autoFlairAttrs.primary_group_flair_color,
+          primary_group_name: autoFlairAttrs.primary_group_name,
+        };
+      }
+    }
+  },
+});
diff --git a/app/assets/javascripts/discourse/app/lib/avatar-flair.js b/app/assets/javascripts/discourse/app/lib/avatar-flair.js
new file mode 100644
index 0000000..5e6ee0e
--- /dev/null
+++ b/app/assets/javascripts/discourse/app/lib/avatar-flair.js
@@ -0,0 +1,66 @@
+let _autoGroupFlair, _noAutoFlair;
+
+export default function autoGroupFlairForUser(site, user) {
+  if (!_autoGroupFlair) {
+    initializeAutoGroupFlair(site);
+  }
+
+  if (_noAutoFlair) {
+    // No automatic groups have flair.
+    return null;
+  }
+
+  if (user.admin && _autoGroupFlair.admins) {
+    return _autoGroupFlair.admins;
+  }
+
+  if (user.moderator && _autoGroupFlair.moderators) {
+    return _autoGroupFlair.moderators;
+  }
+
+  if (_autoGroupFlair.staff && (user.admin || user.moderator)) {
+    return _autoGroupFlair.staff;
+  }
+
+  let trustLevel = user.trust_level || user.trustLevel;
+
+  if (trustLevel) {
+    for (let i = trustLevel; i >= 0; i--) {
+      if (_autoGroupFlair[`trust_level_${i}`]) {
+        return _autoGroupFlair[`trust_level_${i}`];
+      }
+    }
+  }
+}
+
+export function resetFlair() {
+  _autoGroupFlair = null;
+  _noAutoFlair = null;
+}
+
+function initializeAutoGroupFlair(site) {
+  _autoGroupFlair = {};
+  _noAutoFlair = true;
+
+  [
+    "admins",
+    "moderators",
+    "staff",
+    "trust_level_0",
+    "trust_level_1",
+    "trust_level_2",
+    "trust_level_3",
+    "trust_level_4",
+  ].forEach((groupName) => {
+    const group = site.groups.findBy("name", groupName);
+    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, " "),
+      };
+    }
+  });
+}
diff --git a/app/assets/javascripts/discourse/app/lib/transform-post.js b/app/assets/javascripts/discourse/app/lib/transform-post.js
index 276f806..113a7a7 100644
--- a/app/assets/javascripts/discourse/app/lib/transform-post.js
+++ b/app/assets/javascripts/discourse/app/lib/transform-post.js
@@ -81,6 +81,7 @@ export function transformBasicPost(post) {
     userCustomFields: post.user_custom_fields,
     readCount: post.readers_count,
     canPublishPage: false,
+    trustLevel: post.trust_level,
   };
 
   _additionalAttributes.forEach((a) => (postAtts[a] = post[a]));
diff --git a/app/assets/javascripts/discourse/app/templates/components/groups-form-profile-fields.hbs b/app/assets/javascripts/discourse/app/templates/components/groups-form-profile-fields.hbs
index 5be10c5..e8ef91e 100644
--- a/app/assets/javascripts/discourse/app/templates/components/groups-form-profile-fields.hbs
+++ b/app/assets/javascripts/discourse/app/templates/components/groups-form-profile-fields.hbs
@@ -26,6 +26,12 @@
   {{d-editor value=model.bio_raw class="group-form-bio input-xxlarge"}}
 </div>
 
+{{#if model.automatic}}
+  <div class="control-group">
+    {{group-flair-inputs model=model}}
+  </div>
+{{/if}}
+
 {{#if canEdit}}
   {{yield}}
 
diff --git a/app/assets/javascripts/discourse/app/templates/components/latest-topic-list-item.hbs b/app/assets/javascripts/discourse/app/templates/components/latest-topic-list-item.hbs
index f890437..754d9fd 100644
--- a/app/assets/javascripts/discourse/app/templates/components/latest-topic-list-item.hbs
+++ b/app/assets/javascripts/discourse/app/templates/components/latest-topic-list-item.hbs
@@ -2,6 +2,7 @@
   {{#user-link user=topic.lastPosterUser}}
     {{avatar topic.lastPosterUser imageSize="large"}}
   {{/user-link}}
+  {{user-avatar-flair user=topic.lastPosterUser}}
   {{#if topic.lastPosterGroup}}
     {{avatar-flair
       flairURL=topic.lastPosterGroup.flair_url
diff --git a/app/assets/javascripts/discourse/app/templates/components/user-card-contents.hbs b/app/assets/javascripts/discourse/app/templates/components/user-card-contents.hbs
index b14298c..f6f6c47 100644
--- a/app/assets/javascripts/discourse/app/templates/components/user-card-contents.hbs
+++ b/app/assets/javascripts/discourse/app/templates/components/user-card-contents.hbs
@@ -27,13 +27,9 @@
           {{else}}
             <a href={{this.user.path}} {{action "showUser" this.user}} class="card-huge-avatar">{{bound-avatar this.user "huge"}}</a>
           {{/if}}
-          {{#if this.user.primary_group_name}}
-            {{avatar-flair
-            flairURL=this.user.primary_group_flair_url
-            flairBgColor=this.user.primary_group_flair_bg_color
-            flairColor=this.user.primary_group_flair_color
-            groupName=this.user.primary_group_name}}
-          {{/if}}
+
+          {{user-avatar-flair user=this.user}}
+
           {{plugin-outlet name="user-card-avatar-flair" args=(hash user=this.user) tagName="div"}}
         </div>
         <div class="names">
diff --git a/app/assets/javascripts/discourse/app/templates/components/user-info.hbs b/app/assets/javascripts/discourse/app/templates/components/user-info.hbs
index 6de329c..07c80f4 100644
--- a/app/assets/javascripts/discourse/app/templates/components/user-info.hbs
+++ b/app/assets/javascripts/discourse/app/templates/components/user-info.hbs
@@ -1,13 +1,7 @@
 <div class="user-image">
   <div class="user-image-inner">
     <a href={{this.userPath}} data-user-card={{@user.username}}>{{avatar @user imageSize="large"}}</a>
-    {{#if @user.primary_group_name}}
-      {{avatar-flair
-        flairURL=@user.primary_group_flair_url
-        flairBgColor=@user.primary_group_flair_bg_color
-        flairColor=@user.primary_group_flair_color
-        groupName=@user.primary_group_name}}
-    {{/if}}
+    {{user-avatar-flair user=@user}}
   </div>
 </div>
 
diff --git a/app/assets/javascripts/discourse/app/templates/components/user-profile-avatar.hbs b/app/assets/javascripts/discourse/app/templates/components/user-profile-avatar.hbs
index f2965aa..e8b53b6 100644
--- a/app/assets/javascripts/discourse/app/templates/components/user-profile-avatar.hbs
+++ b/app/assets/javascripts/discourse/app/templates/components/user-profile-avatar.hbs
@@ -1,11 +1,5 @@
 <div class="user-profile-avatar">
   {{bound-avatar @user "huge"}}
-  {{#if @user.primary_group_name}}
-    {{avatar-flair
-      flairURL=@user.primary_group_flair_url
-      flairBgColor=@user.primary_group_flair_bg_color
-      flairColor=@user.primary_group_flair_color

[... diff too long, it was truncated ...]

GitHub sha: e8a9917d

1 Like

This commit appears in #12586 which was approved by eviltrout. It was merged by nlalonde.