DEV: Make chatMessage.cook function async (#21829)

This will make it simpler to work with this code. This also can make this code more stable and increase stability of our test suite.

Cooked message now will be available immediately after cooking, it wasn't the case before:

    await message.cook();
    const cooked = message.cooked;


This also removes a call to `message.cook()` from message fabricator. Alternatively we may leave the call there and make the fabricator function async, but I fill it's better this way. If someone needs to test something related to cooked message, they can either pass cooked text to fabricator:

    message = fabricators.message({ cooked: "<p>cooked</p>" });

or call `message.cook()` after fabrication:

    message = fabricators.message({ message: "raw message" });
    await message.cook()
This commit is contained in:
Andrei Prigorshnev 2023-06-01 13:39:32 +04:00 committed by GitHub
parent 128d67ba56
commit d086888549
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 75 additions and 66 deletions

View File

@ -647,11 +647,11 @@ export default class ChatLivePane extends Component {
}
@action
onSendMessage(message) {
async onSendMessage(message) {
if (message.editing) {
this.#sendEditMessage(message);
await this.#sendEditMessage(message);
} else {
this.#sendNewMessage(message);
await this.#sendNewMessage(message);
}
}
@ -660,8 +660,8 @@ export default class ChatLivePane extends Component {
this.chatChannelComposer.reset(this.args.channel);
}
#sendEditMessage(message) {
message.cook();
async #sendEditMessage(message) {
await message.cook();
this.chatChannelPane.sending = true;
const data = {
@ -671,16 +671,21 @@ export default class ChatLivePane extends Component {
this.resetComposer();
return this.chatApi
.editMessage(this.args.channel.id, message.id, data)
.catch(popupAjaxError)
.finally(() => {
this.chatDraftsManager.remove({ channelId: this.args.channel.id });
this.chatChannelPane.sending = false;
});
try {
return await this.chatApi.editMessage(
this.args.channel.id,
message.id,
data
);
} catch (e) {
popupAjaxError(e);
} finally {
this.chatDraftsManager.remove({ channelId: this.args.channel.id });
this.chatChannelPane.sending = false;
}
}
#sendNewMessage(message) {
async #sendNewMessage(message) {
this.chatChannelPane.sending = true;
resetIdle();
@ -712,7 +717,7 @@ export default class ChatLivePane extends Component {
);
}
this.args.channel.stageMessage(message);
await this.args.channel.stageMessage(message);
this.resetComposer();
if (!this.args.channel.canLoadMoreFuture) {

View File

@ -216,13 +216,13 @@ export default class ChatThreadPanel extends Component {
}
@action
onSendMessage(message) {
async onSendMessage(message) {
resetIdle();
if (message.editing) {
this.#sendEditMessage(message);
await this.#sendEditMessage(message);
} else {
this.#sendNewMessage(message);
await this.#sendNewMessage(message);
}
}
@ -236,7 +236,7 @@ export default class ChatThreadPanel extends Component {
this.chat.activeMessage = null;
}
#sendNewMessage(message) {
async #sendNewMessage(message) {
message.thread = this.thread;
if (this.chatChannelThreadPane.sending) {
@ -245,7 +245,7 @@ export default class ChatThreadPanel extends Component {
this.chatChannelThreadPane.sending = true;
this.thread.stageMessage(message);
await this.thread.stageMessage(message);
this.resetComposer();
this.scrollToBottom();
@ -272,8 +272,8 @@ export default class ChatThreadPanel extends Component {
});
}
#sendEditMessage(message) {
message.cook();
async #sendEditMessage(message) {
await message.cook();
this.chatChannelThreadPane.sending = true;
const data = {
@ -283,12 +283,17 @@ export default class ChatThreadPanel extends Component {
this.resetComposer();
return this.chatApi
.editMessage(message.channel.id, message.id, data)
.catch(popupAjaxError)
.finally(() => {
this.chatChannelThreadPane.sending = false;
});
try {
return await this.chatApi.editMessage(
message.channel.id,
message.id,
data
);
} catch (e) {
popupAjaxError(e);
} finally {
this.chatChannelThreadPane.sending = false;
}
}
// A more consistent way to scroll to the bottom when we are sure this is our goal

View File

@ -10,7 +10,11 @@ export default class ChatStyleguideChatMessage extends Component {
manager = new ChatMessagesManager(getOwner(this));
message = fabricators.message({ user: this.currentUser });
constructor() {
super(...arguments);
this.message = fabricators.message({ user: this.currentUser });
this.message.cook();
}
@action
toggleDeleted() {
@ -61,9 +65,9 @@ export default class ChatStyleguideChatMessage extends Component {
}
@action
updateMessage(event) {
async updateMessage(event) {
this.message.message = event.target.value;
this.message.cook();
await this.message.cook();
}
@action

View File

@ -46,8 +46,6 @@ function messageFabricator(args = {}) {
message.excerpt = text.slice(0, excerptLength) + "...";
}
message.cook();
return message;
}

View File

@ -286,12 +286,12 @@ export default class ChatChannel {
return thread;
}
stageMessage(message) {
async stageMessage(message) {
message.id = guid();
message.staged = true;
message.draft = false;
message.createdAt ??= moment.utc().format();
message.cook();
await message.cook();
if (message.inReplyTo) {
if (!this.threadingEnabled) {

View File

@ -7,7 +7,7 @@ import I18n from "I18n";
import { generateCookFunction } from "discourse/lib/text";
import simpleCategoryHashMentionTransform from "discourse/plugins/chat/discourse/lib/simple-category-hash-mention-transform";
import { getOwner } from "discourse-common/lib/get-owner";
import { next } from "@ember/runloop";
export default class ChatMessage {
static cookFunction = null;
@ -147,40 +147,37 @@ export default class ChatMessage {
}
}
cook() {
async cook() {
const site = getOwner(this).lookup("service:site");
next(() => {
if (this.isDestroyed || this.isDestroying) {
return;
}
if (this.isDestroyed || this.isDestroying) {
return;
}
const markdownOptions = {
featuresOverride:
site.markdown_additional_options?.chat?.limited_pretty_text_features,
markdownItRules:
site.markdown_additional_options?.chat
?.limited_pretty_text_markdown_rules,
hashtagTypesInPriorityOrder:
site.hashtag_configurations?.["chat-composer"],
hashtagIcons: site.hashtag_icons,
const markdownOptions = {
featuresOverride:
site.markdown_additional_options?.chat?.limited_pretty_text_features,
markdownItRules:
site.markdown_additional_options?.chat
?.limited_pretty_text_markdown_rules,
hashtagTypesInPriorityOrder:
site.hashtag_configurations?.["chat-composer"],
hashtagIcons: site.hashtag_icons,
};
if (ChatMessage.cookFunction) {
this.cooked = ChatMessage.cookFunction(this.message);
} else {
const cookFunction = await generateCookFunction(markdownOptions);
ChatMessage.cookFunction = (raw) => {
return simpleCategoryHashMentionTransform(
cookFunction(raw),
site.categories
);
};
if (ChatMessage.cookFunction) {
this.cooked = ChatMessage.cookFunction(this.message);
} else {
generateCookFunction(markdownOptions).then((cookFunction) => {
ChatMessage.cookFunction = (raw) => {
return simpleCategoryHashMentionTransform(
cookFunction(raw),
site.categories
);
};
this.cooked = ChatMessage.cookFunction(this.message);
});
}
});
this.cooked = ChatMessage.cookFunction(this.message);
}
}
get read() {

View File

@ -63,12 +63,12 @@ export default class ChatThread {
}
}
stageMessage(message) {
async stageMessage(message) {
message.id = guid();
message.staged = true;
message.draft = false;
message.createdAt ??= moment.utc().format();
message.cook();
await message.cook();
this.messagesManager.addMessages([message]);
}