@@ -4,24 +4,31 @@ async function DeleteAllReplies(userName, waitAfterDelete, waitBetweenDeleteAtte
44 }
55
66 function isVisible ( el ) {
7- return el && el . offsetParent !== null ;
7+ return el && ! ! ( el . offsetWidth || el . offsetHeight || el . getClientRects ( ) . length ) ;
8+ }
9+
10+ function isReplyByUser ( article , userName ) {
11+ const userLink = article . querySelector ( `a[href^="/${ userName } "]` ) ;
12+ const repostMarker = article . innerText . includes ( "Reposted" ) ;
13+ return userLink && ! repostMarker ;
814 }
915
1016 async function waitForReplyCaret ( maxWait = 5000 , interval = 200 ) {
1117 const start = Date . now ( ) ;
1218 while ( Date . now ( ) - start < maxWait ) {
13- const caret = document . querySelector ( "article[data-testid='tweet'] button[data-testid='caret']" ) ;
14- if ( caret && isVisible ( caret ) ) return true ;
19+ const articles = Array . from ( document . querySelectorAll ( "article[data-testid='tweet']" ) ) ;
20+ const match = articles . find ( article => isReplyByUser ( article , userName ) ) ;
21+ if ( match ) return true ;
1522
16- window . scrollBy ( 0 , 500 ) ;
23+ window . scrollBy ( 0 , 600 ) ;
1724 await delay ( interval ) ;
1825 }
1926 return false ;
2027 }
2128
22- async function findCaretWithRetry ( article , maxRetries = 5 , delayMs = 300 ) {
29+ async function findCaretWithRetry ( article , maxRetries = 5 , delayMs = 200 ) {
2330 for ( let i = 0 ; i < maxRetries ; i ++ ) {
24- const caret = article . querySelector ( "button[data-testid='caret'] " ) ;
31+ const caret = article . querySelector ( "div[aria-label='More']/div > div > div " ) ;
2532 if ( caret && isVisible ( caret ) ) return caret ;
2633 await delay ( delayMs ) ;
2734 }
@@ -35,10 +42,8 @@ async function DeleteAllReplies(userName, waitAfterDelete, waitBetweenDeleteAtte
3542 for ( const item of menuItems ) {
3643 const span = item . querySelector ( "span" ) ;
3744 if ( ! span ) continue ;
38-
39- const color = getComputedStyle ( span ) . color ;
40- const [ r , g , b ] = color . match ( / \d + / g) . map ( Number ) ;
41- if ( r > 180 && g < 100 && b < 100 ) {
45+ const text = span . innerText . toLowerCase ( ) ;
46+ if ( text . includes ( "delete" ) ) {
4247 span . click ( ) ;
4348 return true ;
4449 }
@@ -50,7 +55,7 @@ async function DeleteAllReplies(userName, waitAfterDelete, waitBetweenDeleteAtte
5055 async function tryConfirmDelete ( attempts , baseDelay ) {
5156 for ( let i = 0 ; i < attempts ; i ++ ) {
5257 await delay ( baseDelay * ( i + 1 ) ) ;
53- const confirmBtn = document . querySelector ( "button[data-testid='confirmationSheetConfirm']" ) ;
58+ const confirmBtn = document . querySelector ( "div[role='dialog'] button[data-testid='confirmationSheetConfirm']" ) ;
5459 if ( confirmBtn && isVisible ( confirmBtn ) ) {
5560 confirmBtn . click ( ) ;
5661 return true ;
@@ -61,13 +66,13 @@ async function DeleteAllReplies(userName, waitAfterDelete, waitBetweenDeleteAtte
6166
6267 async function clickDeleteOnReply ( ) {
6368 const articles = Array . from ( document . querySelectorAll ( "article[data-testid='tweet']" ) ) ;
64- const replyArticle = articles . find ( article => article . querySelector ( `a[href*="/ ${ userName } "]` ) ) ;
69+ const replyArticle = articles . find ( article => isReplyByUser ( article , userName ) ) ;
6570 if ( ! replyArticle ) {
6671 console . log ( "[clickDeleteOnReply] No matching reply article found." ) ;
6772 return false ;
6873 }
6974
70- const caret = await findCaretWithRetry ( replyArticle , 6 , 300 ) ;
75+ const caret = await findCaretWithRetry ( replyArticle ) ;
7176 if ( ! caret ) {
7277 console . log ( "[clickDeleteOnReply] Caret not found in reply article." ) ;
7378 return false ;
@@ -76,13 +81,13 @@ async function DeleteAllReplies(userName, waitAfterDelete, waitBetweenDeleteAtte
7681 caret . click ( ) ;
7782 await delay ( waitBetweenDeleteAttempts ) ;
7883
79- const deleteClicked = await tryClickDeleteMenuItem ( 5 , waitBetweenDeleteAttempts ) ;
84+ const deleteClicked = await tryClickDeleteMenuItem ( 3 , waitBetweenDeleteAttempts ) ;
8085 if ( ! deleteClicked ) {
8186 console . log ( "[clickDeleteOnReply] Failed to click delete menu item." ) ;
8287 return false ;
8388 }
8489
85- const confirmed = await tryConfirmDelete ( 5 , waitBetweenDeleteAttempts ) ;
90+ const confirmed = await tryConfirmDelete ( 3 , waitBetweenDeleteAttempts ) ;
8691 if ( ! confirmed ) {
8792 console . log ( "[clickDeleteOnReply] Failed to confirm deletion." ) ;
8893 return false ;
@@ -95,7 +100,7 @@ async function DeleteAllReplies(userName, waitAfterDelete, waitBetweenDeleteAtte
95100 window . deletedReplies = 0 ;
96101
97102 while ( true ) {
98- const found = await waitForReplyCaret ( 5000 , 200 ) ;
103+ const found = await waitForReplyCaret ( 7000 , 200 ) ;
99104 if ( ! found ) {
100105 console . log ( "[DeleteAllReplies] No more visible replies." ) ;
101106 break ;
0 commit comments