🐛 | Fix message input
This commit is contained in:
@@ -67,31 +67,75 @@ scoped.onDispose(() => removeCss());
|
||||
|
||||
// ── Helper: find and fill the message input ─────────────────────
|
||||
function setMessageInput(text) {
|
||||
// Find the Discord chat textarea
|
||||
const textarea = document.querySelector(
|
||||
'main [class*="channelTextArea"] textarea, ' +
|
||||
'main [class*="channelTextArea"] [role="textbox"], ' +
|
||||
'[class*="chat"] [class*="channelTextArea"] textarea, ' +
|
||||
'[class*="chat"] [class*="channelTextArea"] [role="textbox"]'
|
||||
);
|
||||
// Broad selectors for Discord's chat input (textarea or contenteditable div)
|
||||
const selectors = [
|
||||
// Modern Discord: Slate-based contenteditable div
|
||||
'[class*="channelTextArea"] div[role="textbox"][contenteditable="true"]',
|
||||
'[class*="channelTextArea"] [data-slate-editor="true"]',
|
||||
// Classic Discord: textarea inside channelTextArea
|
||||
'[class*="channelTextArea"] textarea',
|
||||
// Fallback: role="textbox" anywhere inside channelTextArea
|
||||
'[class*="channelTextArea"] [role="textbox"]',
|
||||
// Even broader fallbacks (no main/chat prefix)
|
||||
'main [class*="channelTextArea"] textarea',
|
||||
'main [class*="channelTextArea"] [role="textbox"]',
|
||||
'[class*="chat"] [class*="channelTextArea"] textarea',
|
||||
'[class*="chat"] [class*="channelTextArea"] [role="textbox"]',
|
||||
];
|
||||
|
||||
let textarea = null;
|
||||
for (const sel of selectors) {
|
||||
textarea = document.querySelector(sel);
|
||||
if (textarea) break;
|
||||
}
|
||||
|
||||
if (!textarea) return false;
|
||||
|
||||
// The native textarea (or contenteditable div) inside
|
||||
const nativeInput = textarea.tagName === "TEXTAREA"
|
||||
? textarea
|
||||
: textarea.querySelector("textarea");
|
||||
// Determine the native input element
|
||||
let nativeInput;
|
||||
const isContentEditable =
|
||||
textarea.tagName !== "TEXTAREA" &&
|
||||
(textarea.isContentEditable || textarea.getAttribute("contenteditable") === "true");
|
||||
|
||||
if (textarea.tagName === "TEXTAREA") {
|
||||
// Classic Discord: direct textarea element
|
||||
nativeInput = textarea;
|
||||
} else if (isContentEditable) {
|
||||
// Modern Discord: Slate/contenteditable div - use it directly
|
||||
nativeInput = textarea;
|
||||
} else {
|
||||
// Look for a nested textarea (older layout)
|
||||
nativeInput = textarea.querySelector("textarea");
|
||||
}
|
||||
|
||||
if (!nativeInput) return false;
|
||||
|
||||
// Set the native value
|
||||
// Set the value
|
||||
nativeInput.focus();
|
||||
nativeInput.value = text;
|
||||
|
||||
if (nativeInput.tagName === "TEXTAREA") {
|
||||
// Classic textarea input
|
||||
nativeInput.value = text;
|
||||
} else {
|
||||
// ContentEditable div (Slate editor / modern Discord)
|
||||
// Clear existing content and insert new text
|
||||
nativeInput.textContent = "";
|
||||
nativeInput.focus();
|
||||
|
||||
// Use execCommand as fallback for Slate-based editors
|
||||
try {
|
||||
document.execCommand("insertText", false, text);
|
||||
} catch (_) {
|
||||
// Fallback: set textContent directly
|
||||
nativeInput.textContent = text;
|
||||
}
|
||||
}
|
||||
|
||||
// Dispatch an input event so React picks up the change
|
||||
const nativeInputEv = new Event("input", { bubbles: true, cancelable: true });
|
||||
nativeInput.dispatchEvent(nativeInputEv);
|
||||
|
||||
// Also dispatch on the outer element if it's a contenteditable
|
||||
// Also dispatch on the outer element if it differs and is contenteditable
|
||||
if (textarea !== nativeInput && textarea.isContentEditable) {
|
||||
textarea.textContent = text;
|
||||
textarea.dispatchEvent(new Event("input", { bubbles: true }));
|
||||
|
||||
Reference in New Issue
Block a user