diff --git a/app/assets/javascripts/discourse/app/components/user-info.js b/app/assets/javascripts/discourse/app/components/user-info.js
index 9fdcf782c6a..d211ec1eff3 100644
--- a/app/assets/javascripts/discourse/app/components/user-info.js
+++ b/app/assets/javascripts/discourse/app/components/user-info.js
@@ -12,6 +12,16 @@ export default Component.extend({
includeLink: true,
includeAvatar: true,
+ didInsertElement() {
+ this._super(...arguments);
+ this.user?.trackStatus?.();
+ },
+
+ willDestroyElement() {
+ this._super(...arguments);
+ this.user?.stopTrackingStatus?.();
+ },
+
@discourseComputed("user.username")
userPath(username) {
return userPath(username);
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 98f868a492f..9e32ff4303e 100644
--- a/app/assets/javascripts/discourse/app/templates/components/user-info.hbs
+++ b/app/assets/javascripts/discourse/app/templates/components/user-info.hbs
@@ -28,7 +28,10 @@
{{/if}}
{{#if (and @showStatus @user.status)}}
-
+
{{/if}}
diff --git a/app/assets/javascripts/discourse/app/templates/group-index.hbs b/app/assets/javascripts/discourse/app/templates/group-index.hbs
index 0408dd2e1a1..6f431a1a06f 100644
--- a/app/assets/javascripts/discourse/app/templates/group-index.hbs
+++ b/app/assets/javascripts/discourse/app/templates/group-index.hbs
@@ -54,7 +54,11 @@
{{/if}}
-
+
|
diff --git a/app/assets/javascripts/discourse/tests/integration/components/user-info-test.js b/app/assets/javascripts/discourse/tests/integration/components/user-info-test.js
index 604481403b9..57092a42b57 100644
--- a/app/assets/javascripts/discourse/tests/integration/components/user-info-test.js
+++ b/app/assets/javascripts/discourse/tests/integration/components/user-info-test.js
@@ -1,6 +1,6 @@
import { module, test } from "qunit";
import { setupRenderingTest } from "discourse/tests/helpers/component-test";
-import { render } from "@ember/test-helpers";
+import { render, triggerEvent } from "@ember/test-helpers";
import { hbs } from "ember-cli-htmlbars";
import { exists, query } from "discourse/tests/helpers/qunit-helpers";
@@ -91,4 +91,58 @@ module("Integration | Component | user-info", function (hooks) {
assert.notOk(exists(".user-status-message"));
});
+
+ test("doesn't show status description by default", async function (assert) {
+ this.currentUser.name = "Evil Trout";
+ this.currentUser.status = { emoji: "tooth", description: "off to dentist" };
+
+ await render(
+ hbs``
+ );
+
+ assert
+ .dom(".user-status-message .user-status-message-description")
+ .doesNotExist();
+ });
+
+ test("shows status description if enabled", async function (assert) {
+ this.currentUser.name = "Evil Trout";
+ this.currentUser.status = { emoji: "tooth", description: "off to dentist" };
+
+ await render(
+ hbs``
+ );
+
+ assert
+ .dom(".user-status-message .user-status-message-description")
+ .exists();
+ });
+
+ test("doesn't show status tooltip by default", async function (assert) {
+ this.currentUser.name = "Evil Trout";
+ this.currentUser.status = { emoji: "tooth", description: "off to dentist" };
+
+ await render(
+ hbs``
+ );
+ await triggerEvent(query(".user-status-message"), "mouseenter");
+
+ assert.notOk(
+ document.querySelector("[data-tippy-root] .user-status-message-tooltip")
+ );
+ });
+
+ test("shows status tooltip if enabled", async function (assert) {
+ this.currentUser.name = "Evil Trout";
+ this.currentUser.status = { emoji: "tooth", description: "off to dentist" };
+
+ await render(
+ hbs``
+ );
+ await triggerEvent(query(".user-status-message"), "mouseenter");
+
+ assert.ok(
+ document.querySelector("[data-tippy-root] .user-status-message-tooltip")
+ );
+ });
});
diff --git a/app/assets/stylesheets/common/base/group.scss b/app/assets/stylesheets/common/base/group.scss
index 6bf464c1702..388635e451b 100644
--- a/app/assets/stylesheets/common/base/group.scss
+++ b/app/assets/stylesheets/common/base/group.scss
@@ -162,6 +162,13 @@ table.group-members {
.avatar-flair {
color: var(--primary);
}
+
+ .user-status-message {
+ img.emoji {
+ width: 1em;
+ height: 1em;
+ }
+ }
}
}
diff --git a/app/controllers/groups_controller.rb b/app/controllers/groups_controller.rb
index d4b856d73ba..830f3ad230f 100644
--- a/app/controllers/groups_controller.rb
+++ b/app/controllers/groups_controller.rb
@@ -301,8 +301,8 @@ class GroupsController < ApplicationController
users = users
.includes(:primary_group)
- .joins(:user_option)
- .select('users.*, user_options.timezone, group_users.created_at as added_at')
+ .includes(:user_option)
+ .select('users.*, group_users.created_at as added_at')
.order(order)
.order(username_lower: dir)
diff --git a/app/serializers/group_user_serializer.rb b/app/serializers/group_user_serializer.rb
index 0c1d9a43951..fa5bbda7867 100644
--- a/app/serializers/group_user_serializer.rb
+++ b/app/serializers/group_user_serializer.rb
@@ -8,10 +8,22 @@ class GroupUserSerializer < BasicUserSerializer
:last_posted_at,
:last_seen_at,
:added_at,
- :timezone
+ :timezone,
+ :status
+
+ def timezone
+ user.user_option.timezone
+ end
def include_added_at?
object.respond_to? :added_at
end
+ def include_status?
+ SiteSetting.enable_user_status && user.has_status?
+ end
+
+ def status
+ UserStatusSerializer.new(user.user_status, root: false)
+ end
end
diff --git a/plugins/chat/assets/javascripts/discourse/components/direct-message-creator.hbs b/plugins/chat/assets/javascripts/discourse/components/direct-message-creator.hbs
index 02ae6ecb222..83efb708d08 100644
--- a/plugins/chat/assets/javascripts/discourse/components/direct-message-creator.hbs
+++ b/plugins/chat/assets/javascripts/discourse/components/direct-message-creator.hbs
@@ -48,7 +48,12 @@
{{on "keyup" (action "handleUserKeyUp" user)}}
>
-
+
{{/each}}
diff --git a/spec/serializers/group_user_serializer_spec.rb b/spec/serializers/group_user_serializer_spec.rb
new file mode 100644
index 00000000000..e9e19c090e0
--- /dev/null
+++ b/spec/serializers/group_user_serializer_spec.rb
@@ -0,0 +1,47 @@
+# frozen_string_literal: true
+
+RSpec.describe GroupUserSerializer do
+ let(:serializer) { described_class.new(user, scope: Guardian.new(user), root: false) }
+
+ describe '#status' do
+ fab!(:user_status) { Fabricate(:user_status) }
+ fab!(:user) { Fabricate(:user, user_status: user_status) }
+
+ it "adds user status when enabled in site settings" do
+ SiteSetting.enable_user_status = true
+
+ json = serializer.as_json
+
+ expect(json[:status]).to_not be_nil do |status|
+ expect(status.description).to eq(user_status.description)
+ expect(status.emoji).to eq(user_status.emoji)
+ end
+ end
+
+ it "doesn't add user status when disabled in site settings" do
+ SiteSetting.enable_user_status = false
+ json = serializer.as_json
+ expect(json.keys).not_to include :status
+ end
+
+ it "doesn't add expired user status" do
+ SiteSetting.enable_user_status = true
+
+ user.user_status.ends_at = 1.minutes.ago
+ serializer = described_class.new(user, scope: Guardian.new(user), root: false)
+ json = serializer.as_json
+
+ expect(json.keys).not_to include :status
+ end
+
+ it "doesn't return status if user doesn't have it" do
+ SiteSetting.enable_user_status = true
+
+ user.clear_status!
+ user.reload
+ json = serializer.as_json
+
+ expect(json.keys).not_to include :status
+ end
+ end
+end
|