Stabilize MAX composer focus for sending
This commit is contained in:
+51
-1
@@ -2194,6 +2194,10 @@ async function sendTextAndConfirm(p, externalChatId, text) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function fillComposerText(p, text, clearFirst) {
|
async function fillComposerText(p, text, clearFirst) {
|
||||||
|
if (clearFirst && await fillComposerViaLocator(p, text)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
for (let attempt = 0; attempt < 2; attempt++) {
|
for (let attempt = 0; attempt < 2; attempt++) {
|
||||||
if (!(await focusComposer(p))) {
|
if (!(await focusComposer(p))) {
|
||||||
break;
|
break;
|
||||||
@@ -2246,6 +2250,40 @@ async function fillComposerText(p, text, clearFirst) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function fillComposerViaLocator(p, text) {
|
||||||
|
const selectors = [
|
||||||
|
"[data-testid='composer'] [role='textbox']",
|
||||||
|
"[data-testid='composer'] [contenteditable='true']",
|
||||||
|
"[class*='composer' i] [role='textbox']",
|
||||||
|
"[class*='composer' i] [contenteditable='true']",
|
||||||
|
"[class*='composer' i] [class*='contenteditable' i]",
|
||||||
|
"[role='textbox'][class*='contenteditable' i]"
|
||||||
|
];
|
||||||
|
|
||||||
|
for (const selector of selectors) {
|
||||||
|
try {
|
||||||
|
const composer = p.locator(selector).last();
|
||||||
|
if ((await composer.count()) === 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
await composer.scrollIntoViewIfNeeded({ timeout: 2000 }).catch(() => {});
|
||||||
|
await composer.click({ timeout: 3000 });
|
||||||
|
await composer.fill("", { timeout: 3000 });
|
||||||
|
await composer.fill(text, { timeout: 3000 });
|
||||||
|
await p.waitForTimeout(200);
|
||||||
|
const currentText = await readComposerText(p);
|
||||||
|
if (currentText !== null && messageTextMatches(currentText, text)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
// Try the next composer shape.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
async function focusComposer(p) {
|
async function focusComposer(p) {
|
||||||
const point = await p.evaluate(() => {
|
const point = await p.evaluate(() => {
|
||||||
const cleanText = (value) => String(value || "")
|
const cleanText = (value) => String(value || "")
|
||||||
@@ -2301,6 +2339,7 @@ async function focusComposer(p) {
|
|||||||
.map((element) => {
|
.map((element) => {
|
||||||
const rect = element.getBoundingClientRect();
|
const rect = element.getBoundingClientRect();
|
||||||
return {
|
return {
|
||||||
|
element,
|
||||||
x: Math.round(rect.left + rect.width / 2),
|
x: Math.round(rect.left + rect.width / 2),
|
||||||
y: Math.round(rect.top + rect.height / 2),
|
y: Math.round(rect.top + rect.height / 2),
|
||||||
bottom: Math.round(rect.bottom),
|
bottom: Math.round(rect.bottom),
|
||||||
@@ -2308,7 +2347,18 @@ async function focusComposer(p) {
|
|||||||
};
|
};
|
||||||
})
|
})
|
||||||
.sort((a, b) => b.bottom - a.bottom || b.area - a.area);
|
.sort((a, b) => b.bottom - a.bottom || b.area - a.area);
|
||||||
return candidates[0] || {
|
const candidate = candidates[0];
|
||||||
|
if (candidate?.element instanceof HTMLElement) {
|
||||||
|
candidate.element.scrollIntoView({ block: "center", inline: "nearest" });
|
||||||
|
candidate.element.focus({ preventScroll: true });
|
||||||
|
const rect = candidate.element.getBoundingClientRect();
|
||||||
|
return {
|
||||||
|
x: Math.round(rect.left + rect.width / 2),
|
||||||
|
y: Math.round(rect.top + rect.height / 2)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
x: Math.round(window.innerWidth * 0.55),
|
x: Math.round(window.innerWidth * 0.55),
|
||||||
y: Math.round(window.innerHeight - 40)
|
y: Math.round(window.innerHeight - 40)
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user