blob: a5bf48d28aa77f2e436a30c7a04bde7f4562e97a [file] [log] [blame]
Adrià Vilanova Martínez115e3d82023-01-10 21:50:06 +01001import '@material/web/button/outlined-button.js';
2
3import {css, html, LitElement} from 'lit';
4import {waitFor} from 'poll-until-promise';
5
6import {SHARED_MD3_STYLES} from '../../../../common/styles/md3.js';
7import {getExtraInfoNodes} from '../flattenThreads.js';
8
9export default class TwptFlattenThreadReplyButton extends LitElement {
10 static properties = {
11 extraInfo: {type: Object},
12 };
13
14 static styles = [
15 SHARED_MD3_STYLES,
16 css`
17 md-outlined-button {
18 --md-outlined-button-container-shape: 0.25rem;
19 --md-outlined-button-container-height: 38px;
20 }
21 `,
22 ];
23
24 constructor() {
25 super();
26 this.extraInfo = {};
27 }
28
29 render() {
30 return html`
31 <md-outlined-button
32 label="Reply"
33 @click=${this.openReplyEditor}>
34 </md-outlined-button>
35 `;
36 }
37
38 #defaultReply(messagePayload) {
39 const quoteHeader = document.createElement('div');
40 const italics = document.createElement('i');
41 italics.textContent = this.extraInfo?.authorName + ' said:';
42 quoteHeader.append(italics);
43
44 const quote = document.createElement('blockquote');
45 quote.innerHTML = messagePayload;
46 getExtraInfoNodes(quote)?.forEach?.(node => {
47 node.parentNode.removeChild(node);
48 });
49
50 const br1 = document.createElement('br');
51 const br2 = document.createElement('br');
52
53 return [quoteHeader, quote, br1, br2];
54 }
55
56 openReplyEditor() {
57 const messageId = this.extraInfo?.id;
58 const messagePayload = document.querySelector(
59 '[data-twpt-message-id="' + messageId +
60 '"] .scTailwindThreadPostcontentroot html-blob');
61 if (!messagePayload) {
62 console.error('[flattenThreads] Payload not found.');
63 return;
64 }
65
66 const parentId = this.extraInfo?.parentId ?? this.extraInfo?.id;
67 const parentNodeReply =
68 document.querySelector('[data-twpt-message-id="' + parentId + '"]')
69 ?.closest?.('sc-tailwind-thread-message-message-card');
70 const parentNodeReplyButton = parentNodeReply?.querySelector?.(
71 '.scTailwindThreadMessageMessagecardadd-comment button');
72 if (!parentNodeReplyButton) {
73 // This is not critical: the reply button might already have been clicked
74 // (so it no longer exists), or the thread might be locked so replying is
75 // disabled and the button does'nt exist.
76 console.debug('[flattenThreads] Reply button not found.');
77 return;
78 }
79
80 // Click the reply button.
81 parentNodeReplyButton.click();
82
83 // Fill in the default reply text (it includes a quote of the message the
84 // user wishes to reply to).
85 waitFor(() => {
86 const editor =
87 parentNodeReply?.querySelector('sc-tailwind-thread-reply-editor');
88 if (editor) return Promise.resolve(editor);
89 return Promise.reject(new Error('Editor not found.'));
90 }, {interval: 75, timeout: 10 * 1000}).then(editor => {
91 const payload =
92 editor?.querySelector('.scTailwindSharedRichtexteditoreditor');
93
94 payload.prepend(...this.#defaultReply(messagePayload.innerHTML));
Adrià Vilanova Martínezdb38d7f2023-01-10 22:40:58 +010095 payload.scrollTop = payload.scrollHeight;
Adrià Vilanova Martínez115e3d82023-01-10 21:50:06 +010096 });
97 }
98}
99window.customElements.define(
100 'twpt-flatten-thread-reply-button', TwptFlattenThreadReplyButton);