mirror of
https://github.com/discourse/discourse.git
synced 2024-11-23 03:40:00 +08:00
FIX: improvements to chat message streaming (#26892)
- prevents re-rendering avatars while updating messages quickly in the thread preview indicator - ensures the cancel button is shown when you are admin OR when the streamed message is a reply to the current user
This commit is contained in:
parent
42297b2ec3
commit
278eb0a1a5
|
@ -492,7 +492,7 @@ export default class ChatMessage extends Component {
|
||||||
return (
|
return (
|
||||||
this.args.message.streaming &&
|
this.args.message.streaming &&
|
||||||
(this.currentUser.admin ||
|
(this.currentUser.admin ||
|
||||||
this.args.message.user.id === this.currentUser.id)
|
this.args.message.inReplyTo?.user?.id === this.currentUser.id)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -234,7 +234,11 @@ export default class ChatChannelSubscriptionManager {
|
||||||
handleThreadOriginalMessageUpdate(data) {
|
handleThreadOriginalMessageUpdate(data) {
|
||||||
const message = this.messagesManager.findMessage(data.original_message_id);
|
const message = this.messagesManager.findMessage(data.original_message_id);
|
||||||
if (message?.thread) {
|
if (message?.thread) {
|
||||||
message.thread.preview = ChatThreadPreview.create(data.preview);
|
if (message.thread.preview) {
|
||||||
|
message.thread.preview.update(data.preview);
|
||||||
|
} else {
|
||||||
|
message.thread.preview = ChatThreadPreview.create(data.preview);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import { tracked } from "@glimmer/tracking";
|
import { tracked } from "@glimmer/tracking";
|
||||||
import { TrackedArray } from "@ember-compat/tracked-built-ins";
|
|
||||||
|
|
||||||
export default class ChatThreadPreview {
|
export default class ChatThreadPreview {
|
||||||
static create(args = {}) {
|
static create(args = {}) {
|
||||||
|
@ -19,21 +18,37 @@ export default class ChatThreadPreview {
|
||||||
args = {};
|
args = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.update(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
get otherParticipantCount() {
|
||||||
|
return this.participantCount - this.participantUsers.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
update(args = {}) {
|
||||||
this.replyCount = args.reply_count || args.replyCount || 0;
|
this.replyCount = args.reply_count || args.replyCount || 0;
|
||||||
this.lastReplyId = args.last_reply_id || args.lastReplyId;
|
this.lastReplyId = args.last_reply_id || args.lastReplyId;
|
||||||
this.lastReplyCreatedAt = new Date(
|
this.lastReplyCreatedAt = new Date(
|
||||||
args.last_reply_created_at || args.lastReplyCreatedAt
|
args.last_reply_created_at || args.lastReplyCreatedAt
|
||||||
);
|
);
|
||||||
this.lastReplyExcerpt = args.last_reply_excerpt || args.lastReplyExcerpt;
|
this.lastReplyExcerpt = args.last_reply_excerpt || args.lastReplyExcerpt;
|
||||||
this.lastReplyUser = args.last_reply_user || args.lastReplyUser;
|
|
||||||
this.participantCount =
|
this.participantCount =
|
||||||
args.participant_count || args.participantCount || 0;
|
args.participant_count || args.participantCount || 0;
|
||||||
this.participantUsers = new TrackedArray(
|
|
||||||
args.participant_users || args.participantUsers || []
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
get otherParticipantCount() {
|
// cheap trick to avoid avatars flickering
|
||||||
return this.participantCount - this.participantUsers.length;
|
const lastReplyUser = args.last_reply_user || args.lastReplyUser;
|
||||||
|
if (lastReplyUser?.id !== this.lastReplyUser?.id) {
|
||||||
|
this.lastReplyUser = lastReplyUser;
|
||||||
|
}
|
||||||
|
|
||||||
|
// cheap trick to avoid avatars flickering
|
||||||
|
const participantUsers =
|
||||||
|
args.participant_users || args.participantUsers || [];
|
||||||
|
if (
|
||||||
|
participantUsers?.map((u) => u.id).join(",") !==
|
||||||
|
this.participantUsers?.map((u) => u.id).join(",")
|
||||||
|
) {
|
||||||
|
this.participantUsers = participantUsers;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { getOwner } from "@ember/application";
|
import { getOwner } from "@ember/application";
|
||||||
import { render } from "@ember/test-helpers";
|
import { clearRender, render } from "@ember/test-helpers";
|
||||||
import hbs from "htmlbars-inline-precompile";
|
import hbs from "htmlbars-inline-precompile";
|
||||||
import { module, test } from "qunit";
|
import { module, test } from "qunit";
|
||||||
import { setupRenderingTest } from "discourse/tests/helpers/component-test";
|
import { setupRenderingTest } from "discourse/tests/helpers/component-test";
|
||||||
|
@ -58,4 +58,56 @@ module("Discourse Chat | Component | chat-message", function (hooks) {
|
||||||
"has the correct css class"
|
"has the correct css class"
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("Message with streaming", async function (assert) {
|
||||||
|
// admin
|
||||||
|
this.currentUser.admin = true;
|
||||||
|
|
||||||
|
this.message = new ChatFabricators(getOwner(this)).message({
|
||||||
|
inReplyTo: new ChatFabricators(getOwner(this)).message(),
|
||||||
|
streaming: true,
|
||||||
|
});
|
||||||
|
await this.message.cook();
|
||||||
|
await render(template);
|
||||||
|
|
||||||
|
assert
|
||||||
|
.dom(".stop-streaming-btn")
|
||||||
|
.exists("when admin, it has the stop streaming button");
|
||||||
|
|
||||||
|
await clearRender();
|
||||||
|
|
||||||
|
// not admin - not replying to current user
|
||||||
|
this.currentUser.admin = false;
|
||||||
|
|
||||||
|
this.message = new ChatFabricators(getOwner(this)).message({
|
||||||
|
inReplyTo: new ChatFabricators(getOwner(this)).message(),
|
||||||
|
streaming: true,
|
||||||
|
});
|
||||||
|
await this.message.cook();
|
||||||
|
await render(template);
|
||||||
|
|
||||||
|
assert
|
||||||
|
.dom(".stop-streaming-btn")
|
||||||
|
.doesNotExist("when admin, it doesn't have the stop streaming button");
|
||||||
|
|
||||||
|
await clearRender();
|
||||||
|
|
||||||
|
// not admin - replying to current user
|
||||||
|
this.currentUser.admin = false;
|
||||||
|
|
||||||
|
this.message = new ChatFabricators(getOwner(this)).message({
|
||||||
|
inReplyTo: new ChatFabricators(getOwner(this)).message({
|
||||||
|
user: this.currentUser,
|
||||||
|
}),
|
||||||
|
streaming: true,
|
||||||
|
});
|
||||||
|
await this.message.cook();
|
||||||
|
await render(template);
|
||||||
|
|
||||||
|
assert
|
||||||
|
.dom(".stop-streaming-btn")
|
||||||
|
.exists(
|
||||||
|
"when replying to current user, it has the stop streaming button"
|
||||||
|
);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue
Block a user