From 76695567368abff8a6a4cf6e50575c87d85b5560 Mon Sep 17 00:00:00 2001 From: fkysly Date: Thu, 22 Jan 2026 09:56:02 +0800 Subject: [PATCH] fix(x-video): improve video ready detection - Type text while video uploads in background instead of waiting - Fix video ready detection by checking tweet button state instead of progressbar presence (X always has progressbar elements for video playback, causing false negatives) --- skills/baoyu-post-to-x/scripts/x-video.ts | 49 +++++++++++++---------- 1 file changed, 27 insertions(+), 22 deletions(-) diff --git a/skills/baoyu-post-to-x/scripts/x-video.ts b/skills/baoyu-post-to-x/scripts/x-video.ts index 62ec303..e8789e7 100644 --- a/skills/baoyu-post-to-x/scripts/x-video.ts +++ b/skills/baoyu-post-to-x/scripts/x-video.ts @@ -112,24 +112,44 @@ export async function postVideoToX(options: XVideoOptions): Promise { nodeId, files: [absVideoPath], }, { sessionId }); - console.log('[x-video] Video file set, waiting for processing...'); + console.log('[x-video] Video file set, uploading in background...'); - // Wait for video to process + // Wait a moment for upload to start, then type text while video processes + await sleep(2000); + + // Type text while video uploads in background + if (text) { + console.log('[x-video] Typing text...'); + await cdp.send('Runtime.evaluate', { + expression: ` + const editor = document.querySelector('[data-testid="tweetTextarea_0"]'); + if (editor) { + editor.focus(); + document.execCommand('insertText', false, ${JSON.stringify(text)}); + } + `, + }, { sessionId }); + await sleep(500); + } + + // Wait for video to finish processing by checking if tweet button is enabled + console.log('[x-video] Waiting for video processing...'); const waitForVideoReady = async (maxWaitMs = 180_000): Promise => { const start = Date.now(); let dots = 0; while (Date.now() - start < maxWaitMs) { - const result = await cdp!.send<{ result: { value: { hasMedia: boolean; isProcessing: boolean } } }>('Runtime.evaluate', { + const result = await cdp!.send<{ result: { value: { hasMedia: boolean; buttonEnabled: boolean } } }>('Runtime.evaluate', { expression: `(() => { const hasMedia = !!document.querySelector('[data-testid="attachments"] video, [data-testid="videoPlayer"], video'); - const isProcessing = !!document.querySelector('[role="progressbar"], [data-testid="progressBar"]'); - return { hasMedia, isProcessing }; + const tweetBtn = document.querySelector('[data-testid="tweetButton"]'); + const buttonEnabled = tweetBtn && !tweetBtn.disabled && tweetBtn.getAttribute('aria-disabled') !== 'true'; + return { hasMedia, buttonEnabled }; })()`, returnByValue: true, }, { sessionId }); - const { hasMedia, isProcessing } = result.result.value; - if (hasMedia && !isProcessing) { + const { hasMedia, buttonEnabled } = result.result.value; + if (hasMedia && buttonEnabled) { console.log(''); return true; } @@ -150,21 +170,6 @@ export async function postVideoToX(options: XVideoOptions): Promise { console.log('[x-video] Video may still be processing. Please check browser window.'); } - // Type text AFTER video is uploaded - if (text) { - console.log('[x-video] Typing text...'); - await cdp.send('Runtime.evaluate', { - expression: ` - const editor = document.querySelector('[data-testid="tweetTextarea_0"]'); - if (editor) { - editor.focus(); - document.execCommand('insertText', false, ${JSON.stringify(text)}); - } - `, - }, { sessionId }); - await sleep(500); - } - if (submit) { console.log('[x-video] Submitting post...'); await cdp.send('Runtime.evaluate', {