FEATURE: make user status on post streams live (#17903)

This commit is contained in:
Andrei Prigorshnev 2022-08-29 19:33:50 +04:00 committed by GitHub
parent 6564d04e0d
commit 007980fdaf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 174 additions and 12 deletions

View File

@ -154,6 +154,7 @@ export default function transformPost(
postAtts.topicUrl = topic.get("url");
postAtts.isSaving = post.isSaving;
postAtts.staged = post.staged;
postAtts.user = post.user;
if (post.notice) {
postAtts.notice = post.notice;
@ -290,10 +291,6 @@ export default function transformPost(
postAtts.isDeleted && post.can_permanently_delete;
}
if (post.user_status) {
postAtts.userStatus = post.user_status;
}
_additionalAttributes.forEach((a) => (postAtts[a] = post[a]));
return postAtts;

View File

@ -599,6 +599,7 @@ export default RestModel.extend({
},
prependPost(post) {
this._initUserModel(post);
const stored = this.storePost(post);
if (stored) {
const posts = this.posts;
@ -609,6 +610,7 @@ export default RestModel.extend({
},
appendPost(post) {
this._initUserModel(post);
const stored = this.storePost(post);
if (stored) {
const posts = this.posts;
@ -1245,6 +1247,17 @@ export default RestModel.extend({
}
},
_initUserModel(post) {
post.user = User.create({
id: post.user_id,
username: post.username,
});
if (post.user_status) {
post.user.status = post.user_status;
}
},
_checkIfShouldShowRevisions() {
if (_lastEditNotificationClick) {
const copy = _lastEditNotificationClick;

View File

@ -42,6 +42,20 @@ export default createWidget("poster-name", {
showGlyph: true,
},
didRenderWidget() {
if (this.attrs.user) {
this.attrs.user.trackStatus();
this.attrs.user.on("status-changed", this, "scheduleRerender");
}
},
willRerenderWidget() {
if (this.attrs.user) {
this.attrs.user.off("status-changed", this, "scheduleRerender");
this.attrs.user.stopTrackingStatus();
}
},
// TODO: Allow extensibility
posterGlyph(attrs) {
if (attrs.moderator || attrs.groupModerator) {
@ -151,8 +165,12 @@ export default createWidget("poster-name", {
afterNameContents(attrs) {
const contents = [];
if (this.siteSettings.enable_user_status && attrs.userStatus) {
contents.push(this.attach("post-user-status", attrs.userStatus));
if (
this.siteSettings.enable_user_status &&
attrs.user &&
attrs.user.status
) {
contents.push(this.attach("post-user-status", attrs.user.status));
}
contents.push(...applyDecorators(this, "after-name", attrs, this.state));
return contents;

View File

@ -0,0 +1,127 @@
import {
acceptance,
exists,
publishToMessageBus,
query,
queryAll,
} from "discourse/tests/helpers/qunit-helpers";
import { visit } from "@ember/test-helpers";
import { test } from "qunit";
import TopicFixtures from "discourse/tests/fixtures/topic";
import { cloneJSON } from "discourse-common/lib/object";
acceptance("Topic - User Status", function (needs) {
const status = { emoji: "tooth", description: "off to dentist" };
needs.user();
needs.pretender((server, helper) => {
server.get("/t/299/1.json", () => {
const response = cloneJSON(TopicFixtures["/t/299/1.json"]);
response.post_stream.posts.forEach((post) => {
post.user_status = status;
});
return helper.response(200, response);
});
});
test("shows user status next to avatar on posts", async function (assert) {
this.siteSettings.enable_user_status = true;
await visit("/t/-/299/1");
assert.equal(
queryAll(".topic-post .user-status-message").length,
3,
"all posts has user status"
);
});
});
acceptance("Topic - User Status - live updates", function (needs) {
const userId = 1;
const status = { emoji: "tooth", description: "off to dentist" };
needs.user();
needs.pretender((server, helper) => {
server.get("/t/299/1.json", () => {
const response = cloneJSON(TopicFixtures["/t/299/1.json"]);
response.post_stream.posts.forEach((post) => {
post.user_id = userId;
post.user_status = { emoji: "tooth", description: "off to dentist" };
});
return helper.response(200, response);
});
});
test("updating status", async function (assert) {
this.siteSettings.enable_user_status = true;
await visit("/t/-/299/1");
assert.equal(
queryAll(".topic-post .user-status-message").length,
3,
"all posts has user status"
);
assert.ok(
query(".topic-post .user-status-message .emoji").src.includes(
status.emoji
),
"status emoji is correct"
);
const newStatus = { emoji: "surfing_man", description: "surfing" };
await publishToMessageBus(`/user-status`, { [userId]: newStatus });
assert.equal(
queryAll(".topic-post .user-status-message").length,
3,
"all posts has user status"
);
assert.ok(
query(".topic-post .user-status-message .emoji").src.includes(
newStatus.emoji
),
"status emoji is correct"
);
});
test("removing status and setting again", async function (assert) {
this.siteSettings.enable_user_status = true;
await visit("/t/-/299/1");
assert.equal(
queryAll(".topic-post .user-status-message").length,
3,
"all posts has user status"
);
assert.ok(
query(".topic-post .user-status-message .emoji").src.includes(
status.emoji
),
"status emoji is correct"
);
await publishToMessageBus(`/user-status`, { [userId]: null });
assert.notOk(
exists(".topic-post .user-status-message"),
"status on all posts has disappeared"
);
const newStatus = { emoji: "surfing_man", description: "surfing" };
await publishToMessageBus(`/user-status`, { [userId]: newStatus });
assert.equal(
queryAll(".topic-post .user-status-message").length,
3,
"all posts have user status"
);
assert.ok(
query(".topic-post .user-status-message .emoji").src.includes(
newStatus.emoji
),
"status emoji is correct"
);
});
});

View File

@ -11,6 +11,7 @@ import { hbs } from "ember-cli-htmlbars";
import EmberObject from "@ember/object";
import I18n from "I18n";
import createStore from "discourse/tests/helpers/create-store";
import User from "discourse/models/user";
module("Integration | Component | Widget | post", function (hooks) {
setupRenderingTest(hooks);
@ -920,9 +921,12 @@ module("Integration | Component | Widget | post", function (hooks) {
test("shows user status if enabled in site settings", async function (assert) {
this.siteSettings.enable_user_status = true;
this.set("args", {
userStatus: { emoji: "tooth", description: "off to dentist" },
});
const status = {
emoji: "tooth",
description: "off to dentist",
};
const user = User.create({ status });
this.set("args", { user });
await render(hbs`<MountWidget @widget="post" @args={{this.args}} />`);
@ -931,9 +935,12 @@ module("Integration | Component | Widget | post", function (hooks) {
test("doesn't show user status if disabled in site settings", async function (assert) {
this.siteSettings.enable_user_status = false;
this.set("args", {
userStatus: { emoji: "tooth", description: "off to dentist" },
});
const status = {
emoji: "tooth",
description: "off to dentist",
};
const user = User.create({ status });
this.set("args", { user });
await render(hbs`<MountWidget @widget="post" @args={{this.args}} />`);