FEATURE: show user status on group pages (#19323)
This adds live user status to /g/{group-name} routes.
This commit is contained in:
parent
492f68c462
commit
ff5a0bec89
|
@ -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);
|
||||
|
|
|
@ -28,7 +28,10 @@
|
|||
{{/if}}
|
||||
</span>
|
||||
{{#if (and @showStatus @user.status)}}
|
||||
<UserStatusMessage @status={{@user.status}} @showDescription={{true}} @showTooltip={{false}} />
|
||||
<UserStatusMessage
|
||||
@status={{@user.status}}
|
||||
@showDescription={{@showStatusDescription}}
|
||||
@showTooltip={{@showStatusTooltip}} />
|
||||
{{/if}}
|
||||
<PluginOutlet @name="after-user-name" @tagName="span" @connectorTagName="span" @args={{hash user=this.user}} />
|
||||
</div>
|
||||
|
|
|
@ -54,7 +54,11 @@
|
|||
{{/if}}
|
||||
|
||||
<td class="avatar" colspan="2">
|
||||
<UserInfo @user={{m}} @skipName={{this.skipName}} />
|
||||
<UserInfo
|
||||
@user={{m}}
|
||||
@skipName={{this.skipName}}
|
||||
@showStatus={{true}}
|
||||
@showStatusTooltip={{true}}/>
|
||||
</td>
|
||||
|
||||
<td class="group-owner">
|
||||
|
|
|
@ -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`<UserInfo @user={{this.currentUser}} @showStatus={{true}} />`
|
||||
);
|
||||
|
||||
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`<UserInfo @user={{this.currentUser}} @showStatus={{true}} @showStatusDescription={{true}} />`
|
||||
);
|
||||
|
||||
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`<UserInfo @user={{this.currentUser}} @showStatus={{true}} />`
|
||||
);
|
||||
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`<UserInfo @user={{this.currentUser}} @showStatus={{true}} @showStatusTooltip={{true}} />`
|
||||
);
|
||||
await triggerEvent(query(".user-status-message"), "mouseenter");
|
||||
|
||||
assert.ok(
|
||||
document.querySelector("[data-tippy-root] .user-status-message-tooltip")
|
||||
);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -162,6 +162,13 @@ table.group-members {
|
|||
.avatar-flair {
|
||||
color: var(--primary);
|
||||
}
|
||||
|
||||
.user-status-message {
|
||||
img.emoji {
|
||||
width: 1em;
|
||||
height: 1em;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -48,7 +48,12 @@
|
|||
{{on "keyup" (action "handleUserKeyUp" user)}}
|
||||
>
|
||||
<ChatUserAvatar @user={{user}} @avatarSize="medium" />
|
||||
<UserInfo @user={{user}} @includeLink={{false}} @includeAvatar={{false}} @showStatus={{true}} />
|
||||
<UserInfo
|
||||
@user={{user}}
|
||||
@includeLink={{false}}
|
||||
@includeAvatar={{false}}
|
||||
@showStatus={{true}}
|
||||
@showStatusDescription={{true}} />
|
||||
</li>
|
||||
{{/each}}
|
||||
</ul>
|
||||
|
|
|
@ -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
|
Loading…
Reference in New Issue