1- const sliderWaitTime = document . getElementById ( "slider-wait-time " ) ;
2- const spanWaitTime = document . getElementById ( "wait-time " ) ;
1+ const waitMinInp = document . getElementById ( "inputWaitMin " ) ;
2+ const waitMaxInp = document . getElementById ( "inputWaitMax " ) ;
33const inputMaxPosts = document . getElementById ( "max-posts" ) ;
44const radioAction = document . getElementsByName ( "action" ) ;
55const startBtn = document . getElementById ( "start-btn" ) ;
66
7- sliderWaitTime . value = localStorage . getItem ( "wait-time" ) || 3000 ;
8- spanWaitTime . innerHTML = renderTime ( sliderWaitTime . value ) ;
9- sliderWaitTime . oninput = function ( ) {
10- spanWaitTime . innerHTML = renderTime ( this . value ) ;
11- localStorage . setItem ( "wait-time" , this . value ) ;
12- } ;
7+ function initCacheInput ( input , cacheName ) {
8+ if ( localStorage . getItem ( cacheName ) ) {
9+ input . value = localStorage . getItem ( cacheName ) ;
10+ }
11+ input . addEventListener ( "input" , ( ) => {
12+ localStorage . setItem ( cacheName , input . value ) ;
13+ } ) ;
14+ }
1315
14- function renderTime ( time ) {
15- return ( time / 1000 ) . toFixed ( 1 ) + "s" ;
16+ function renderTime ( time , fixed = 1 ) {
17+ return ( time / 1000 ) . toFixed ( fixed ) + "s" ;
1618}
1719
1820async function main ( ) {
21+ initCacheInput ( waitMinInp , "wait-min" ) ;
22+ initCacheInput ( waitMaxInp , "wait-max" ) ;
23+ initCacheInput ( inputMaxPosts , "max-posts" ) ;
24+
1925 const tab = await getCurrentTab ( ) ;
2026
2127 if ( ! tab . url . includes ( "groups" ) || ! tab . url . includes ( "spam" ) ) {
@@ -26,44 +32,70 @@ async function main() {
2632 }
2733
2834 startBtn . addEventListener ( "click" , async ( ) => {
35+ const state = await getCurrentState ( tab ) ;
36+ if ( state ?. running ) {
37+ return stop ( tab ) ;
38+ }
39+
2940 let action = radioAction [ 0 ] . checked ? 1 : 2 ;
30- let max = parseInt ( inputMaxPosts . value ) ;
31- let wait = parseInt ( sliderWaitTime . value ) ;
41+ let maxPosts = parseInt ( inputMaxPosts . value ) ;
42+ let waitMin = parseInt ( waitMinInp . value ) * 1000 ;
43+ let waitMax = parseInt ( waitMaxInp . value ) * 1000 ;
44+
45+ if ( waitMin > waitMax ) {
46+ return alert (
47+ "Thời gian chờ không hợp lệ\nBên trái phải bé hơn hoặc bằng bên phải"
48+ ) ;
49+ }
50+
3251 runScriptInTab ( {
3352 target : { tabId : tab . id } ,
3453 func : start ,
35- args : [ action , max , wait ] ,
54+ args : [ action , maxPosts , waitMin , waitMax ] ,
3655 } ) ;
3756 } ) ;
3857
3958 // check is running
4059 ( async function checkIsRunning ( ) {
41- const isRunning = await runScriptInTab ( {
42- target : { tabId : tab . id } ,
43- func : ( ) => window . fb_group_ext_running ,
44- } ) ;
45- if ( isRunning ) {
46- // disable button
47- startBtn . disabled = true ;
48- startBtn . innerHTML = "Đang xử lý..." ;
49- startBtn . classList . add ( "disabled" ) ;
60+ const state = await getCurrentState ( tab ) ;
61+ const { running, nextExecuteTime } = state || { } ;
62+ if ( running ) {
63+ startBtn . innerHTML =
64+ "Đang xử lý... (chờ " +
65+ renderTime ( nextExecuteTime - Date . now ( ) , 0 ) +
66+ ")<br/>(<i>Bấm để dừng</i>)" ;
67+ startBtn . classList . add ( "running" ) ;
5068 } else {
51- // enable button
52- startBtn . disabled = false ;
5369 startBtn . innerHTML = "Bắt đầu" ;
54- startBtn . classList . remove ( "disabled " ) ;
70+ startBtn . classList . remove ( "running " ) ;
5571 }
56- setTimeout ( checkIsRunning , 500 ) ;
72+ setTimeout ( checkIsRunning , 1000 ) ;
5773 } ) ( ) ;
5874}
5975
60- function start ( action , max , wait ) {
76+ function getCurrentState ( tab ) {
77+ return runScriptInTab ( {
78+ target : { tabId : tab . id } ,
79+ func : ( ) => window . fb_group_ext ,
80+ } ) ;
81+ }
82+
83+ function stop ( tab ) {
84+ runScriptInTab ( {
85+ target : { tabId : tab . id } ,
86+ func : ( ) => {
87+ window . fb_group_ext . stop = true ;
88+ } ,
89+ } ) ;
90+ }
91+
92+ function start ( action , maxPosts , waitMin , waitMax ) {
6193 const selector =
6294 action == 1
6395 ? '[role="main"] [aria-label="Đăng"]'
6496 : '[role="main"] [aria-label="Từ chối"]' ;
6597
66- if ( max == 0 ) max = Infinity ;
98+ if ( maxPosts == 0 ) maxPosts = Infinity ;
6799
68100 const btns = Array . from ( document . querySelectorAll ( selector ) ) ;
69101
@@ -80,14 +112,14 @@ function start(action, max, wait) {
80112 } ) ;
81113
82114 async function main ( ) {
83- window . fb_group_ext_running = true ;
84-
85- // for test
86- // setTimeout(() => (window.fb_group_ext_running = false), 5000);
87- // return ;
115+ window . fb_group_ext = {
116+ running : true ,
117+ nextExecuteTime : 0 ,
118+ stop : false ,
119+ } ;
88120
89121 let counter = 0 ;
90- while ( counter < max ) {
122+ while ( counter < maxPosts && ! window . fb_group_ext . stop ) {
91123 if ( btns . length > 0 ) {
92124 const btn = btns . shift ( ) ;
93125
@@ -96,18 +128,34 @@ function start(action, max, wait) {
96128 btn . click ( ) ;
97129
98130 counter ++ ;
131+ const waitTime = ranInt ( waitMin , waitMax ) ;
132+ window . fb_group_ext . nextExecuteTime = Date . now ( ) + waitTime ;
133+ await sleep ( waitTime , ( ) => window . fb_group_ext . stop ) ;
134+ } else {
135+ // wait for load more
136+ await sleep ( 1000 ) ;
99137 }
100-
101- if ( wait ) await sleep ( wait ) ;
102138 }
103- window . fb_group_ext_running = false ;
139+
140+ window . fb_group_ext . running = false ;
104141 alert ( "Duyệt xong " + counter + " bài" ) ;
105142 }
106143
107144 main ( ) ;
108145
109- function sleep ( time ) {
110- return new Promise ( ( resolve ) => setTimeout ( resolve , time ) ) ;
146+ function ranInt ( min , max ) {
147+ return Math . floor ( Math . random ( ) * ( max - min ) + min ) ;
148+ }
149+
150+ function sleep ( time , cancelFn ) {
151+ return new Promise ( ( resolve ) => {
152+ setTimeout ( resolve , time ) ;
153+ if ( cancelFn ) {
154+ setInterval ( ( ) => {
155+ if ( cancelFn ( ) ) resolve ( ) ;
156+ } , 100 ) ;
157+ }
158+ } ) ;
111159 }
112160
113161 function onElementsAdded ( selector , callback , once ) {
0 commit comments