DEV: Glimmerize ChatMessageActionsDesktop/Mobile components (#20325)

These are fairly small components, so we can change to using
glimmer without too much trouble.
This commit is contained in:
Martin Brennan 2023-02-16 20:24:29 +10:00 committed by GitHub
parent 004228f6c4
commit 9704d9aed6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 92 additions and 78 deletions

View File

@ -1,56 +1,61 @@
<div class="chat-message-actions-container" data-id={{this.message.id}}>
<div
class="chat-message-actions-container"
data-id={{@message.id}}
{{did-insert this.attachPopper}}
{{will-destroy this.destroyPopper}}
>
<div class="chat-message-actions">
{{#if this.chatStateManager.isFullPageActive}}
{{#each this.emojiReactions as |reaction|}}
{{#each @emojiReactions as |reaction|}}
<ChatMessageReaction
@reaction={{reaction}}
@react={{this.messageActions.react}}
@react={{@messageActions.react}}
@class="show"
/>
{{/each}}
{{/if}}
{{#if this.messageCapabilities.canReact}}
{{#if @messageCapabilities.canReact}}
<DButton
@class="btn-flat react-btn"
@action={{this.messageActions.startReactionForMessageActions}}
@action={{@messageActions.startReactionForMessageActions}}
@icon="discourse-emojis"
@title="chat.react"
/>
{{/if}}
{{#if this.messageCapabilities.canBookmark}}
{{#if @messageCapabilities.canBookmark}}
<DButton
@class="btn-flat bookmark-btn"
@action={{this.messageActions.toggleBookmark}}
@action={{@messageActions.toggleBookmark}}
>
<BookmarkIcon @bookmark={{this.message.bookmark}} />
<BookmarkIcon @bookmark={{@message.bookmark}} />
</DButton>
{{/if}}
{{#if this.messageCapabilities.canReply}}
{{#if @messageCapabilities.canReply}}
<DButton
@class="btn-flat reply-btn"
@action={{this.messageActions.reply}}
@action={{@messageActions.reply}}
@icon="reply"
@title="chat.reply"
/>
{{/if}}
{{#if this.messageCapabilities.hasThread}}
{{#if @messageCapabilities.hasThread}}
<DButton
@class="btn-flat chat-message-thread-btn"
@action={{this.messageActions.openThread}}
@action={{@messageActions.openThread}}
@icon="puzzle-piece"
@title="chat.threads.open"
/>
{{/if}}
{{#if this.secondaryButtons.length}}
{{#if @secondaryButtons.length}}
<DropdownSelectBox
@class="more-buttons"
@options={{hash icon="ellipsis-v" placement="left"}}
@content={{this.secondaryButtons}}
@content={{@secondaryButtons}}
@onChange={{action "handleSecondaryButtons"}}
/>
{{/if}}

View File

@ -1,4 +1,4 @@
import Component from "@ember/component";
import Component from "@glimmer/component";
import { action } from "@ember/object";
import { createPopper } from "@popperjs/core";
import { schedule } from "@ember/runloop";
@ -6,25 +6,28 @@ import { inject as service } from "@ember/service";
const MSG_ACTIONS_VERTICAL_PADDING = -10;
export default Component.extend({
tagName: "",
export default class ChatMessageActionsDesktop extends Component {
@service chatStateManager;
chatStateManager: service(),
messageActions: null,
didReceiveAttrs() {
this._super(...arguments);
popper = null;
@action
destroyPopper() {
this.popper?.destroy();
this.popper = null;
}
@action
attachPopper() {
this.destroyPopper();
schedule("afterRender", () => {
this.popper = createPopper(
document.querySelector(
`.chat-message-container[data-id="${this.message.id}"]`
`.chat-message-container[data-id="${this.args.message.id}"]`
),
document.querySelector(
`.chat-message-actions-container[data-id="${this.message.id}"] .chat-message-actions`
`.chat-message-actions-container[data-id="${this.args.message.id}"] .chat-message-actions`
),
{
placement: "top-end",
@ -39,10 +42,10 @@ export default Component.extend({
}
);
});
},
}
@action
handleSecondaryButtons(id) {
this.messageActions?.[id]?.();
},
});
this.args.messageActions?.[id]?.();
}
}

View File

@ -1,4 +1,10 @@
<div class="chat-message-actions-backdrop">
<div
class={{concat-class
"chat-message-actions-backdrop"
(if this.showFadeIn "fade-in")
}}
{{did-insert this.fadeAndVibrate}}
>
<div
role="button"
class="collapse-area"
@ -9,7 +15,7 @@
<div class="chat-message-actions">
<div class="selected-message-container">
<div class="selected-message">
<ChatUserAvatar @user={{this.message.user}} />
<ChatUserAvatar @user={{@message.user}} />
<span
{{on "touchstart" this.expandReply passive=true}}
role="button"
@ -18,13 +24,13 @@
(if this.hasExpandedReply "is-expanded")
}}
>
{{this.message.message}}
{{@message.message}}
</span>
</div>
</div>
<ul class="secondary-actions">
{{#each this.secondaryButtons as |button|}}
{{#each @secondaryButtons as |button|}}
<li class="chat-message-action-item" data-id={{button.id}}>
<DButton
@class="chat-message-action"
@ -32,23 +38,21 @@
@icon={{button.icon}}
@actionParam={{button.id}}
@action={{action
"actAndCloseMenu"
(get this.messageActions button.id)
this.actAndCloseMenu
(get @messageActions button.id)
}}
/>
</li>
{{/each}}
</ul>
{{#if
(or this.messageCapabilities.canReact this.messageCapabilities.canReply)
}}
{{#if (or @messageCapabilities.canReact @messageCapabilities.canReply)}}
<div class="main-actions">
{{#if this.messageCapabilities.canReact}}
{{#each this.emojiReactions as |reaction|}}
{{#if @messageCapabilities.canReact}}
{{#each @emojiReactions as |reaction|}}
<ChatMessageReaction
@reaction={{reaction}}
@react={{this.messageActions.react}}
@react={{@messageActions.react}}
@class="show"
/>
{{/each}}
@ -56,27 +60,27 @@
<DButton
@class="btn-flat react-btn"
@action={{action
"actAndCloseMenu"
this.messageActions.startReactionForMessageActions
this.actAndCloseMenu
@messageActions.startReactionForMessageActions
}}
@icon="discourse-emojis"
@title="chat.react"
/>
{{/if}}
{{#if this.messageCapabilities.canBookmark}}
{{#if @messageCapabilities.canBookmark}}
<DButton
@class="btn-flat bookmark-btn"
@action={{this.messageActions.toggleBookmark}}
@action={{@messageActions.toggleBookmark}}
>
<BookmarkIcon @bookmark={{this.message.bookmark}} />
<BookmarkIcon @bookmark={{@message.bookmark}} />
</DButton>
{{/if}}
{{#if this.messageCapabilities.canReply}}
{{#if @messageCapabilities.canReply}}
<DButton
@class="chat-message-action reply-btn btn-flat"
@action={{action "actAndCloseMenu" this.messageActions.reply}}
@action={{action "actAndCloseMenu" @messageActions.reply}}
@icon="reply"
@title="chat.reply"
/>

View File

@ -1,43 +1,49 @@
import Component from "@ember/component";
import Component from "@glimmer/component";
import { getOwner } from "discourse-common/lib/get-owner";
import { tracked } from "@glimmer/tracking";
import discourseLater from "discourse-common/lib/later";
import { action } from "@ember/object";
import { isTesting } from "discourse-common/config/environment";
export default Component.extend({
tagName: "",
hasExpandedReply: false,
messageActions: null,
export default class ChatMessageActionsMobile extends Component {
@tracked hasExpandedReply = false;
@tracked showFadeIn = false;
didInsertElement() {
this._super(...arguments);
messageActions = null;
discourseLater(this._addFadeIn);
get capabilities() {
return getOwner(this).lookup("capabilities:main");
}
@action
fadeAndVibrate() {
discourseLater(this.#addFadeIn.bind(this));
if (this.capabilities.canVibrate && !isTesting()) {
navigator.vibrate(5);
}
},
}
@action
expandReply(event) {
event.stopPropagation();
this.set("hasExpandedReply", true);
},
this.hasExpandedReply = true;
}
@action
collapseMenu(event) {
event.stopPropagation();
this.onCloseMenu();
},
this.#onCloseMenu();
}
@action
actAndCloseMenu(fn) {
fn?.();
this.onCloseMenu();
},
this.#onCloseMenu();
}
onCloseMenu() {
this._removeFadeIn();
#onCloseMenu() {
this.#removeFadeIn();
// we don't want to remove the component right away as it's animating
// 200 is equal to the duration of the css animation
@ -48,19 +54,15 @@ export default Component.extend({
// by ensuring we are not hovering any message anymore
// we also ensure the menu is fully removed
this.onHoverMessage?.(null);
this.args.onHoverMessage?.(null);
}, 200);
},
}
_addFadeIn() {
document
.querySelector(".chat-message-actions-backdrop")
?.classList.add("fade-in");
},
#addFadeIn() {
this.showFadeIn = true;
}
_removeFadeIn() {
document
.querySelector(".chat-message-actions-backdrop")
?.classList?.remove("fade-in");
},
});
#removeFadeIn() {
this.showFadeIn = false;
}
}