From 08d735f61ae6cbee2d689f5512bb78af21983156 Mon Sep 17 00:00:00 2001 From: Gabriel Menezes Date: Thu, 5 Nov 2026 11:50:44 -0400 Subject: [PATCH] feat(extension): adicionar deteccao de inatividade com auto-pause e confirmacao de retorno --- vscode-extension/.gitignore | 2 +- vscode-extension/README.md | 3 + vscode-extension/beetask-vscode-1.0.0.vsix | Bin 17307 -> 0 bytes vscode-extension/beetask-vscode-1.1.0.vsix | Bin 0 -> 19486 bytes vscode-extension/package.json | 12 +- vscode-extension/src/commands.ts | 28 ++-- vscode-extension/src/extension.ts | 7 +- vscode-extension/src/idleDetector.ts | 168 +++++++++++++++++++++ 8 files changed, 204 insertions(+), 16 deletions(-) delete mode 100644 vscode-extension/beetask-vscode-1.0.0.vsix create mode 100644 vscode-extension/beetask-vscode-1.1.0.vsix create mode 100644 vscode-extension/src/idleDetector.ts diff --git a/vscode-extension/.gitignore b/vscode-extension/.gitignore index 27950ab..103cee8 100644 --- a/vscode-extension/.gitignore +++ b/vscode-extension/.gitignore @@ -1,5 +1,5 @@ node_modules/ dist/ *.vsix -!beetask-vscode-1.0.0.vsix +!beetask-vscode-*.vsix diff --git a/vscode-extension/README.md b/vscode-extension/README.md index 8985df4..4ce2879 100644 --- a/vscode-extension/README.md +++ b/vscode-extension/README.md @@ -7,6 +7,7 @@ Extensão oficial do **BeeTask** para o Visual Studio Code. Gerencie suas demand ## ✨ Recursos - **⏱️ Cronômetro em Tempo Real:** Acompanhe o tempo trabalhado na tarefa ativa direto na Barra de Status (rodapé do VS Code). +- **🛑 Pausa Automática por Inatividade (10min):** Se você se ausentar do VS Code por mais de 10 minutos com uma tarefa rodando, a extensão pausa o cronômetro automaticamente e pergunta se você ainda está trabalhando nela ao retornar. - **📋 Painel de Tarefas na Barra Lateral:** Visualize rapidamente suas tarefas pendentes, em execução e concluídas na aba BeeTask. - **▶️ Play / ⏸️ Pause com 1 Clique:** Inicie e pause o cronômetro das suas tarefas direto do VS Code. - **➕ Criação Rápida de Tarefas:** Crie novas tarefas associadas a projetos e categorias sem sair do editor. @@ -78,3 +79,5 @@ Acesse `Configurações` (`Ctrl+,`) e busque por `BeeTask`: - `beetask.serverUrl`: URL da API backend (Padrão: `https://api-task.beetech.dev`). - `beetask.webUrl`: URL do site web (Padrão: `https://task.beetech.dev`). - `beetask.refreshIntervalSeconds`: Intervalo de sincronização automática em segundos (Padrão: `30`). +- `beetask.enableIdleDetection`: Ativar pausa automática da tarefa por inatividade (Padrão: `true`). +- `beetask.idleTimeoutMinutes`: Tempo limite de inatividade em minutos (Padrão: `10`). diff --git a/vscode-extension/beetask-vscode-1.0.0.vsix b/vscode-extension/beetask-vscode-1.0.0.vsix deleted file mode 100644 index 2edc8b2f9f465594420b1d65074134a3faaca4c9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 17307 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 diff --git a/vscode-extension/beetask-vscode-1.1.0.vsix b/vscode-extension/beetask-vscode-1.1.0.vsix new file mode 100644 index 0000000000000000000000000000000000000000..79484dc98a109205aef35bfdb2e3fdeb14475dd9 GIT binary patch literal 19486 zcmb4q1FR@rv*odE+qUkpZQHi*v2CAwY}>YN+qO0LdvEgo`QOV-GM#j~lkU#0-Pu)Z zuT@p@QotZ6000mW0Aji(I{0}fJutuk0OU{r0B8UJ04DCvCbmu%cD8h`P8RMq2DTQa zCQi;nsvEY%>@eQ4-GcIZ2MV1c{vr&|L@so&=hmz*~ zo)F)V8jA?+Anb{RgxBN3A=g>y0({(`8RCbh(UI~-K;~d(Cm{ueWhbOvbM%!60 zA675WZXo$cR@U+ML07Bsvqr6Fb1v@uSx9U6v_0oA!Oj|}&*X^h3sl1EZxtKNuKshIdueG!|1O;WPRjMb22 z>VOM|m!PJ=#yQ=2U;DsMP(5Dap9vrw^A2VOOEu=--tPuwaGCf4dTfBVg?^-*&#%fM zMi`kBJp18qu?TD-#nM;J@2K>442L;F-_^}xUKfoM(;;@%7lg$FTk>i*7jxrr0C<8?_3HcV(s7K^zPUCk$3(=dKy`ryXX<<#Iia_r_0 zI*#PpGW|UbEbo7BcU7}d>Eslad^2-AeVl-4g6sNGg{R8;{b0Y=snz($ZxY-i)pU!; zx_*Zftcos+*jRSqstD&N_>7scTE4er&Ru*xSxL36h7nJsMfJ?7Ju69XhJk&aX8q0|Edb|GjDn+1dW}AZI=0-}WX>I&|(f*50#yvI7h-V7njL zMB}JclsE{2Hf|W5fb{xBwkfm@`K!=-R|=RV;f~EcKdC%8nlR;t207-7u{t%V2{H}j z?B^9UAL!m`t^*@#qN=oD`wBV2_Z5uRav1&{N%5L6QdEdR9m<(w`t-ZA+)rN(b>Scq z&-JFK7VZO})dGv2$c0*VZl+Z+EnQ8Pi*Zi3XoKWTW~IH&uQcn{cfvoQl?Sj`C%-6G z2Zbq8IlXPEs;^_-TJa{Acp5R9)lGJY;`HKkr{i4`CT$=#D5re1AYbrZ8l@ zPzR2h>SktLoIP^dJz zxxgt9h?UEioO4cOd?#plPutN9i6tU|E{*bAT4i_)?MWoBhzhjrUFC;lSDu9A6k z;Y9Lrhi`|K&!WTakU-xFVVUrDl5G|-Nq$~xiG*ua*7sPLERjRKC=fsmPO*` zN9trn7h=@T3c2TX0!C+Ao>o-TE@Ub~^91dkJ%y&XiquGOYd;PU;5FWfBMJ+L=eN~d z?am#+y78!0DQa^?8*0Ofvi)5L)-ChtZi$+N1HY!_$7Jil_2T!M8sWao+;n|izg!g;@t5qtWoAA?=+kDanEO;STiW}<^c%Xzq&$7^klzAP zhmhLl;4RF2>M;kf4oze|Yk)#8n`8R5CFU0RIHvCI@0ty6i@k@M*2=vjims%LEG!~j zB_-0MWv=Q@q)+<~8;uA%7bOpi4zsNIX~bz>l9xjkwY&7Y>UGd?EOSU`Fq1-B)D=R? zj;HS1lqc%sJS!RWjDmLLWX>x|s;tGO6cKA42>63!L}lVU$7*A5mfkOo-VGh6fG=Su z+{|r$Lrapr+fX*Ept<0wP4&nXY-231dar7MxDm$;3_mE$TS6@1;cSaH@o$*?!IwuZ z90yDu$!y%S+iUYw1qoAyh6+6T6=F8C3vLi}wf#X|X&my+{ou78xqmw?j{UGd0KoGm zktW^ zWlL4bQFLxvAi(&x_hltMi&O|fUg9Lq+IX8`S^=!9aR1QgnOKZbuHMZrP@8`^-8zNG z_7Y7!IU|1BUcMeyGfvdjwz~W}BG$p66)qoPq(l~E2vY0Z-ugWv;UAZO1@#0>)vKsl zu3Q6umT^E3EFt^AQljRwXiL*8fDpdSnYWG>e30NehYu= zMd{wG_gT}x41sCtOdG9G>P56%ps!;^SlUf?kP}r@hz|N}bVej635ue#zF9x6E+!!_ za?+Cs2SfVpz2jN3>gQl%EbqJPyqeH5LQ4&ed0<*>Fyye_^&SSKSZ|OHCDlWrhKdnn!jlPV#FCaqTHfLUO61J1@}Z`lMG@ z*>mmwkRrQTO~~ruY9nn~SF2OVhBqc>aN&A;kR5IS#aiy*fWvsJVs7cwS6&JnLfWMx z_#FfQfch^y{5y77)#8#(g8=}v!~G|A{MX)#-qFOs*v5p;#yD85F9v%Av1>*Rr4m{q zu|Nm2?Y6l%N#8$tkVY*aR_T&1!Dh-iy2De{$^gD?#Ls#a5@95~c9gIl5I11Z|K=0< zi~kW);At{WNHhi>`ub5?t*hKerRE*ZOWHa38#Cz?A)8Kr_|NWE1^v(c^AX?o!@>l~ zZ+qO)_p2QYcax+(9F_s|#cS;7KUpwx(KQUABBhOc=48P;al{oc{x!3K#Xwb}@E~yB z_QntxK&Yfb_N{|nfqw+B#Q>q}{Rfjvpu{tJ;aL3Fzm+mrWBZfiIrdNzan4NSBvig2U*^+ug$bc8rv z-aGWnh7l}ZALvAF8Z9crz`;Wqg$q>(DlldF0qhP`$-U-RZN_d(J1gG3_Xq-IRMCrv zf-aBxYY=GE5)T;YO13qM14Egfl%iCgpH)myK0!;3Ef>H%F1HTL-)nXI`re3CAc>eD zuux>W1p4h_X87vTMK><=2yq|+zPb^k^x-w^qj#pE*Oq~n8z2+-js)*j;! z%A7*P;5T4#3dDzy#n;ypJcAP$wpZ$g7Gzl}kOPZTNU!5oL&$am6NN5<y=ZzeIL|=c1@o+V@wh|zk z&=CVT^ax0xxl zZURFGr%R6=YCGR>rrHddTKEiN;bDEyCZ@$_p!?fk4^>OePsp+_ zs-cGE?d&=v7eT5TKgIFD)@WKk2Zn|#`$Kb#2OK#H}JWWtOM(?Q(_lbrb3YF z1hFx^R1%mk{d$#T$7@M3qIt~~69>i}0Oin6atbZp`^-TC6-Lm@D4hF*9V~hAh2 zwleyKmT7_on~yu$1kFSGP=8x=x0;5+x@i*q;HZJzSCei^?fExW@W(+)t$&(X+$%si ziEXzy825auEJIesi=sGKQBkiTW&GLxrW}r`fCPHu|IStJeuFxmMlr^51LbJlZK{L4 z?;7}4m}JJV2VJY2{Xm_#MOZ?BXw=ByIXWt_sZ~m=BPCr+uQL}pDgR=+cO9x;MSdDP z3Qk&E`_$&@$7xC&t(So)%GvIUEJ}yKR3aoTlPNFTp1Tq7C$k%@14;mw02-#~utPIu z$LJ{&ZodR8(rR`mJ^E#!la7vJ2AR%pPF|c~;A+))ERy&vboZEvZ35JOMGN6HMm^2m z9}*}tRXK|<-R+J$f{?O2fp?9qSHIO=Hiok_#EnfhCi6nN$&$6fVrrL=F=mYPlYl+y zdSbtgR6K`)5w;G?-0Cl)MG3K3f3Ch<%Ey4C8I3G8Q(9`+xE{qsv5uYZAU?eS&Wyj#G@iVfAW&x)A)n9vbsT?k3JWf^i1>VJH!=m=<(aCQAwKbj)H1k z)rdfCyz`u3)%&2?QYS(1#5{TyUrv}(+eTP7Hi|aOL2)OR>kF0GY@*a|OC=BWPnU42O%>iclA|jR ze|b&?gEaxFcH*u=OyeeeVK?_N)5GTD`ThnUtBZk}>6UXl{usH$rOtd2oSv~xRTT4? z^u)Ln;yA;mz<4p!iyKgeB-AL6!*8}=?;C&8ax>#5doEGduV6Hklh>@dlg3L8<6AO$ z9D{A6YjkN&P0sraigMOtXhrL$nc~?hVO4jdBGZ?xBDe6kytrkRODdip{4AW`M3EDj z(=M_vpwb9MNQUWLx@Cp}FO%2M8ueE1ElFL8yHs3`M$WQo#RS#;LTyQLAPd?pj!J38 zYtK^(bsb%gG&!QLKcN3257FxXP9FXW691AO=%pouL}Zmj{^FmG!i4Px148EmH5g}; zUmP0e<19Aq9GXHp3q^Z%Y`w4;jj;m48Q9y0p$WNnCdBpiOx-_gd6>Ug7(NS;HTv zee4nO6>o0kcM#$6(c`CCfggxVUzYnL<-A+TCh3aTS_b3$Vz2D4%tKqAcj>>Y`EQ4O zj45}qbeb>I_mH@Ji&toyi!Us0>t<$u=kw|$P9T)E9;U^|${C0{5A?1x{6?>H|7zG` z5~`3xF>e<`DZ8H!o#>JEGCsNBeqZeXT>u@drTBKX$%l&08DI!PuU`(SdpM-Yn`EO zOGOa{vv9n^n{WxNqAPeFEqPOt8cH1&sZ&Wp0eMX|t@CjFKDn}x$JCm(ifFotZFkkd z$fUcbwa?bhwHxbiHoSFb<>pMHN|c)V7?h8WNy{w7mlO=>HGl{cZ(u*eY}+k?2HXq zMYMM)o-r+xJ+T#(vCSi!5lV^fLYQ)p(*CfZ!a+`?dBf*RlRLREp*!hPF&Tq~7q*Xa z&tI|&4ne_&LF@wr06_P53-_<}Yp3?_>lgjs)~}6;v4sJ>p@|8dldIX)9~rw1QG}46 z@qo5f@EA8&vmWgQ@B(qgUJ-w=GuB*6Nki#KAPL{66?CEb1RAN7fMpAWQ~iki;fmim z-fpczAC+wxVWAn0%OrD+HYX+I_lT47N$~Ex9JBWIEO7RlJp(sb8>*wCqxNS;=7Ju12ExF@_DCSfG(-`L}zb;boSL*`GE^W_i)I$(m#f7#1E*k|_y0Y90D zEx9P4-H5YX8KsjW9`NCw{>*ocmDiWYii$APFO0ZXgJPH@0ThAaxe+?B$~EMBa}S*! zeqNHSWiK2(}#khI&}zb|l4-Se5|WO&6Ri49&IaP!Gbys_vo zMMjF|ps?!@BKn1>hyDS0WOSl+F8jq7`|f;<;zA5a?9*EK$~7QeRpdo5g1_zOp&j-6 z@%kfjR90794068+CWZ6|Y-UCH=V@&LC|0Uocc2ykVW6g^oGEP*9lPj)F)6kp!)Zrv zg-RWE1ChLK^X05E^6!I*K>G7k)n_&7LE<~G=r8o`SD~Twt27oCLTwicv>||SZf3eg zWK+{l9oLJGO?6=Hc(!VHX7L)o{f|SP9`a`_Gji8v$VxpFj$qWcw_$(v6R_W;f1?Zh z?*ZPRMerbUnvtN)SAYZuc&6Rd1-uOdoHWDsauj%Nr)NAAbOt<{%+;$vButAeL~29Y zhgpXKrd_tEHTeyd9P=F*tsXpdlP$EA8(Q(3CGwAF;L+#&Y@KpEeb}aVQdL-yjCgr1 z&f5>T>})64!s+HOJrvbi8s_ZS&q#drxN8#}d=!ow;wele9?ROR8a{=xrb|T7!VQbr zzLyOLP5(?k_{71V*({)(UFLUIq34_&IAk}ynrJWm<^%Kn6p<+F&J|kVba=G#QF9JR z9Q9|-JJ^Wy4q?;Eg+*ea9m4{duO_#GpgD)Lx$L!v<;~p+cWvaq05Wgb*F@F7r2(y7 z^j9H(R|l^IAzQUke^99mx#7XC{nIVYpa!XkYuU$ZJn|8@q#vS~ix8((54@IToI10O z>tBFcKOD$jZWIZYS?8TB0`8wt0=$uB;@ZB6;~XoarftQ)kzF;f|7zf-W}aLEyvC!g zg)`cXxK;yQKg_!`s|lNO0lcDl)O(&sKmodq!v^uu+oju2>Vwe%l-djDd#s3r0N$*F zZwP1oqOV1_YN`9uYFq(pzKy}4H5@e%4I@wyX!l~^*$``Igv$T6-I|i)gExEa@9N6` zp=w^?J?kMa{P(S}i);T&+4={QDp-EUA`1do)u$#jp4L2kA;@9;_qr-`x%ZQZ&l>rY zpT9vL9Af9W>Yx`C0Dy_~{{(@5@+bc#fBwDscMvePaB`-1{znD=D}sXd^+5&jBY^F8 z$T3={0%_bx*u{|un5`}Ms582yrK6I1ymZf?f|f}{9Iu~0XCh3+x)*_V8HcR;3=V5Z zTR9E@T-~diw*KjE3~AeyCIfx^)ugh3BkmL*M#oTc^wp|I-^{!ych2Yk^N+du&`0Q& ze+{zzd;SZv{=2zEf1mzKa`;bk4VT0W&QWqTls)crwenJFNS z$;3LgO+w*ML=6pmfWMk;U5ji~ER!;dr?i!MozD|MtnW{-IzTjPPyDG{?xq+^AaS4f3eHuwdOKH6*H4M=R(T8rbxOx8 zRa~SUx}!!nk2gU8>%bQMdN*W<^4VWGqV^QV)lu*!;OqiAShOD&UcL{ZTq-n(8KXb? z5Re=D@>S710Q+hJzyJbjr&v3$Bg1>`3dZ#_%>vfy@-;>tgv;z9;>PV40KnkmQ}1_u zzsh-{vh8Fw!*u}tK^o~Fy&-qms9LMBDK~-Fm~N&R7e|5PIg5a*$t(c@F~pT@M9_f* zz~en7`;9{MOcNlCYK?}3#?`TJI?KE1Kuw=2uADGdxew`L?!_De2`vGJiZQ%s@jm7MQ&wljmu#eRlK8UocVoEHMwkK_`5Q5ix1{ zgyrw9^+9eEC`YB5p6dMutw_!9-TRCeD!3X^sIsW%qg4_%kB*iI8B;uGHXjKi2v zRFR6}Wk_)~Nto%`&^xuU#CYIPBFLU8%-XSv5mE3hQA$&s^jcy9n`S}&8yca9iPl{a z!_uxaLUfMunBqzPM_dPKJu--^8%aX_D9qBQ$V$0NAA&I5{2eXXC!AZB*)h}>hqzJ- z)1(h5XzrV-`$-ydQm36^_93C&DAfhODW2QxHA!C`*^K>+!St^*WZpPoU=X7aP1} zTSO%?4KD+kb-8}A#i&A{U$7lwf7RC>)&H3qa%H(}`0c^Nk(fX*j2&fw-z|J!K$E^) z5%!1O!^~BweD+u!mWXhEw0JK(&z>4E$WdbfHJ5ZVvaPtFZO!CL6BYG)h^sb@aZ{wI zoUR&1q^Qs`aO)ym5h)EMhccK@$=lr{RPs0T;-BDF_b-av^pe>QTTDY5sE3PK~@RYP%YVbX-Ihx;`7CsxaEj;uVTfu z0&!%7Q40&FjOM}IgwCS-SiX?`p#{efTabYnf_oN55n?6~IU@RoDhch3^uxPcJedb= zO5>HMq9L+4ljL}NRbER;0Y0&uR+L)_{ONji_S=&V`}hGLR5H79BPXl`hb;`afxX&m z6;Ry2AH?fM5fwu42AW-!<<8B(T2BV&_HDwq1N%j5yvSSFK7xT@|OfOB9 z`2kSSi*>gZFF~E~JsnV=PQZW+1k?LGT3;SLzQe2@sRo?7Ai|G0=^r%}{yFf($ia!t z>1qAh(|5M*UoSlt@So!22ABy}z(&kMcbiyu4%l$aX075X*_KzTVZ7z;8#|2@v#A2 zYD3x7(ogKZzL({w3-%W5>WGHm!?Nu=hDg#h27(fY$+8kkP^?wPlv3%&_S9=J_}c0e zjfu^rspEOmthLZ|($G7*P>CYT`s{W7C5%(8ZXzE-yjUH$P(q&q}#Sx%(4}9~} z6h2Q^13ESy4Z)Aa4HLXgS_7iQ*ey5d6q|B8%?2|TXn2BY?qeJID$I(f%0%kY4wHrG z8o~Icu29)Ae0)=36(sW-LhduF++{lFq{faooi@17_k`T8auRz;J3=#SQ$pHQmaUBg zjZvBOzQ$9YAc}0s-e-+$5YEAlk8Va58G=Ej18Nf*0pB!g@e{aP(P;LI^YQKL(%IS= z{tVg4NvsRG>4SF;HQ#WR?i6Fp(UoUwkp$ToSqYwzgXv|rH07~j$DEo&#En6HT%%p2 zW#n2Hp0+q9vK$qvUwzGmDL$hM?xduCiW(J`1oZ)$hVXMSMnE|neq7q%Q%{W`~ zgv|OdCcYV|x7AT&`RuMmu;1rOZqy$KUbl{DhKsDJuz}b%-)I4RXA-+ToAEEJIEf;i zZI-4Axl5Me(}nxOO6kKCqmIPGZ@rfv0a(C5=nYF1h;%5W1;r0s#mC=DbOBW@0I$y*3Ax3-^hw`YN?$Ci zXHUF9v`R+@h*C&&{pe;hp~{30+pAz_YX6{X>wbqD95?`g3)cT9x;i-Oien@*!#L65o|imnLQ&rExl?&{X|9!WtzVTfqx4Cj zIFyZk1u-Tu4gX%22~?l~CT7Tkz+l<(Eae>w0Kja=ZBd`IZjib0Dq2n1b}vxSQ6~&` zN`5;E*iwq)O@>yvLwGz&T}bf3VSr*KDe^^8-ne!H3XiaW=Gv$@Y7lB-zF0rY9Yvc& zq{Ju>a$P5Ryr8B1+9YIol=p2^LzB1y#yz6iF-CWe?7*8p8A*bLqzDW&#tsoyIs4&s zy}46xe~gxR#?a!f$s{9(wlev>PijKygs4-qp6%|sbI41|4bwTAHK;)R0Z+JTuwfI< z+4n^EXItvF%q^bsl=sN4OvW>HqyryRv`T)>zA+Gbl30pTpkJmbmeFi-imGIB9D_}v z$0jicmO5jfbHE)^fu?;2eMbMqq~hf)&vrRYrziN-Oi+P(1_*C&BhP^(6~wre6n{0h z`Y*Q?D#9h{jtBP!bwAW1+`;PKb|D9wYW2BuX+(ysQl_Jf?#T!# z_L(0P50-UbR#&)=d1AX}Bki!G+dfB@E;lMVcuV>`U(>N3`;4PS1eLN`OAM)ZRJW7K z^1H9I_fR4*R9voT)}1@^y`8Y8zAXb0(D2_|amxRo^Rhp|m|bDYI(Z&RH1m{%+hjio zM3RBwXA%t;5bQIp2ieDnG&MUl%PTq#Fo9Rzo83}J3>KrnsI=z$QSJhZKEGW&@Fnzu znz^A77DNCc(-+A8pBqEx-3 z=ps2leT$SQVFljV_NyS4T7vkDiT2b7$QBkDb6oE}MT9%tt;fpwJdS=p3U)WQTpvkQ zZt2R(3UUN65*lCnn|HT(p zh+c7U+H!(vNNw*9we7^9`yr`joFc)npvV!(m?59zuA!xhTYFeJ@l{A1knUhV-fZz8 z?T}>{BEpOEUgc2<2!DFR<9W`USW)Qv9j@>|RL(avPu2A+^d7`@jKLpYwu`+7DS^oV zwwa&xyaNdond8dP#e2r(`>Zi5MZpchpTbKUfjG5@OekTlm1A)C5My}3;dFzaQ)XsD z%w&bVpd@P8L^Ew>TyBZ`V+M7Eq35har)S=36$za=OClOq>r-z>^g)PdgL!ps9RAC0 z5pD`RaZGD=z8s>)JcY6D`ynWBS*MJl}i$pb8m ztxbeYoK1|J?f!{UMe0+Io5P6R50sjX6OmP#2B{Kysg@X$P3Vo zoN4~1U{Z6Byn%LY6<*?`YAQuuJM3f7hp39cG_|iSi2{ zp(EfsxEQE-DLcfbw~1W6<*+BubCCZR|t1&$O`Wx~d;UkhEF zJDckKq*p`I7$@CWTt9v>{B%xKr&K)kc1pFSSRnbm`B63%=A~5;E4BS#_b3`$AH5dq z9?*@}qTyt{UX%(i59tZTv*q_gdbslKCQ#>gC1Is4P~rsJk2C(-{Pcdv0LucF6f^BW z0hv4Q+Es7)&C*Xa>6igx;uq4gzPSoR4AsPC;*gLVah9;%u7rC;Nr?_(l*U)Fxy^px=tgmc&J_xoBK9`Ko=b| zyTJcIc9I-IxyuT~rMp*>K=sI4>J3uB7ksNI6-5c^A7`^YREYqDjY)g-`tveR-Rwns zRT}VD8@JhpcC9q#QnNP*xxpQ*aZR z6)Yqsuv-Czn&f(>s=Q8`G}B)c<0xggiD<5z+>AOxTj$cH8LO4fr);=RdBcu~K!gGz zCfBQ&Nu6i2ac$dBdswdG_be-d0FxHlGFlBuKtdYmg_$>-L*<$}~%|PYmHkI6jB@=PH1#F+0 zFulcDv5DGM7d{|3Zz847;$NTvJQ&(n5HU#KQsHTWf<$0#8fk3WTvJBfzZ(bg0z#LHWEV8&l+Z3PTtiHJI_DJQP850GI zvAI{6iRr^PZOJN-w>kO8PKf6-sHTz6n|jMz2bUS;S~ErOfkE~b2Su!!z$`#Ue`>>; z^|Gsr()(Jc(}m7)w6>&tI1>XsLkr5Kt@S+UndZ85HC+@o(CIYJ)!Hn%&<41sB83Z% z_SY>cYLZV7^N}Y$G|J({=gEr=>O~T27}0>dK16mDd?{5o@5kphGqgtK07IuGoWgN6 zex8^X$Ziry0W}s3psKxOAZdeP-W2bT;c%V{7xlbRMF(tiHKWy6+`wfieI)4Iy1|&%RbV+WXRg%OW-Ohlfyoq@C*x36#s8g#) zQNa}73-GSr#2%wHdQ4W~lU{WUc#?4V@u->2*^sMJV|e!$UbG==l6?Fj_4ikc@7KwT-d_F9XF@`+n3^Yc_fNdrRxY|M zi5OR?(9NU}9|b+-ePZ+s@Q74Q^T6YQnakU>*K=6+8+_x@%FfH`{@q$^E~!uJPNArR zC^{)Z9OIT&wIwWOfegdCN(TC{c@A6pTs*mnWN@4XaA$?EoEY+Ltx%Qz7*r8XDJ^|C zs#w$%+6nnednamiwRs#6taw#}59;eJ3A?;8HvKLv9kgovT!b%O{+inw>IRO#~%y#Wld^*E-k3#buoJ)>~E&5;h7K7yt<;L)(3@!LQQG zZUGiwDI0=SOW-aV6}TcEWhMT!T9@_BK6E|)E{G~wO7YLMKS^sJo4@_V{-QXy+kto7 z_sa3vJ4wY(6JaN&Pv`a3vm5WKIu;4o=G!jb!gBjm-HK7`&CzcA-CC&Tf*X%@(>9EU z1{I{tS3Uy)AHwHHk5p6J%l1ghdS@>MWKfR*;&Nq2j!sCAVHN!HNB0P8>InG4nVG(e zEfLoUjS;Hv%Y6nXyKsMwb(-O`-anWIg#+Op_P1z;>Tk;M|E_Ie|4&T&FRAM_qYT9?Xo@-a}+(Ca`3}^7eR%NpO!uGrbP2A>ra;b|){#&*;B?MtzSRCl4Ed@#)h$ z2jBQ>2is%KfFX_slQf|RF@(O`VNWtbwgj&6YaT#8>#lPL;e0DmhFZI)W5!qom70H$ zL{ZH0^ho)8B?KXPmD$=CSsrAAsC*aLyG7`ZY)B)0yIe6)G^xGW9J_Q*DYp&FiBpVi z8yD5F39WC*rfupKT)g=$ipy(OtyqS_9qUt7nE~&`iuM;XB_y%Rh@~}#+(r-I8UX;< z6Wdbwg;sBR&BgoyYGCP6cF~Q?@)g#G{%NOJQlw@XOmNH^6g^7w*+A`X|6`a1lmvlm zwfP)cQ&XHqp#t_IUQ`vv+L3h-J9b;Fx_nJ^aT^&aO?Hb4eFTXMqIfH_2Z*;@uK;1l z&94r4PFnr!IXqKf_9~FRiP!2(0kOh3DM}wE0DxZfli-AHQ?~jS^1f=Wb7Mbjq<_CVj~ipKXDr6_PK z;Z*BLG`da0asFozp}lLCI*B3nNRSSDXb4ZskF^corF^D9kRI{37P|7GTQHvqPvEmdLJ+ ze9v3}@OC1lU<`e+!tmXhQ;Bcy{kH>!?v0RaSN!+daP8*G7bK2)|4GbzS&x<0lgpE< z4yCxQKhMsBF_VAtyg8knxd{~i$$qd;kK->c6WoF?u$$rqi;;`GGgac1X8nTK?O;1< z^^hA%FJcy6@1K)hYRb6}nWCq7aJd|?DK)_lgW+@B;J|qdrmf;d3hjd_G^UFu2Ty0Y zzy*D#H`LCm%t3O6lyMYa-!H4}xT77Oo$&kraBbNDU($rXy$D5rdlCNcuKkyF|99Ei z$j;_(r-Jc6Li-htl+(uW+qK@^+8oAi5?I!wOlf@>pGNM-2*+$)E}DMSL$*rI=^rheL^rp#le-_JsP{=2ce>in}Ij z;Ba$nahj455)$M?8-#>W^-hvb*n|Q>Ls6cm01sZgd|@@F?SKw30DvsG&YRx3GqC~W zFVFfK;(e<sF_)}LdlKdGKFH1h>l90qp{mat=-*ACJ1q9O7WmW0f4O%ll0Zt;p zO{Qxb|0fY?etiy76_UiNie6hk+4d#JC=%ZV3J#Mb+p^4T2ev&5VNlYi17@`eX?C3y zAJ3#td)c%?BTFBPm1QX^@5_LtNYapmc9KVopmYL`7^5ZhHWKH#m$4>IF0$^@IIHf_ zfaLVDsx8ilsC1J2VUTrA0-P}m{g!o1D=24K-#@Q>rrfiqcm)W?0naKq!Kae@jP@D; zL~Qrh^?rTZI#40V2>^Rn8!&XlM-L-v$xbK9JFvGnBRE5iCm+wn*+rc;CBSBy=Kgn( z5RY^2EL(37AEHCzStv=xZpCurKDG>`-QM%6-lauP+my^V+P?Fk|6M) zR>D}o5s_hkQMyk8A9c~2&xQ? z{RLz)lk8j!*f_BILY;$#Iv~+l*1n~AZuCjU9>AK5pT%NMZl5bHrc zp!Xs=u&^cK-lj=|o&a86=laWIYNJJd(PU`$q$0UIJc1lU_Q0?7>M`%dxBCYf7zP!S z<1S2T>9RbqVwhUE!S{6Ojw!%loLp$8dMH`hFxNb94ocjZS)?|C{&9@;T}OXCEVU~> zAuvem9QfQK-?$gY&*X(9D?SBOr3@&Y5L8gJN3+xRBo~TvD5WD3by>E34o) zTaCwx+pf%o<~K3;G&p`XJRNU{!p(kSWY(D*Pzw`_VO~TJFbegj!0&k5xHBiipLPZ! zoDpGwc*eW4l|kbEy7k+>hm)B^+{nWBI$-pI?Kg2`sLO_e?HbJv=FkLt3#OPP)gU>l z!+V8*_ja0-Ai3Q$rCR3zXqKQuz&&I!o{I4vkK#t=-&@ATv*_yU86IcTk#1J&;u!~I z1YEeSY4uuRrJlgnFo+>|u;d=U<`AaNPHOd@qmdU$kXze?zS85)!;1 zsoh*{NrZYh$@^ZQnER;6IZ4I{aUq(O_q)U$L8|D*kBguilj2)8DUVsz1NYbyF}Am z21ZQ%xLH?impTY!drC{Ti4p&x|GA8=Bmm1rHbRE5=!y}if$-&@?bJqv6>C`--1$CrC{0E~Rw_J~L$EZ`+eUE(7Yzdkb&q(Ff7VY1!o+jhKh=g(j5- zRUUQi;(w@xyUbA?un3MW`$(y)BDGjDL|=ABSIx>xe)pS_Ag&f&HT7LoQ*|417=24$ zI3d(AP=55g&}^Q+gS(cn$bw5anPe4f5yGzrpoDs$55Q-LM5qkf(UOYfDE3GuKsqS5Y1{ z4z8_8W)`_|R@v4mBi(p=9+#^;lH#4o3^mDEUGO8HRCxF|X%yg4KG%XkzL-2fO5mFqgge48df=_xF zORc;nL0!8-3P&E^soZtrd#jwjH3rtSQBWlOSgQ~%KA~2t-y(H{u1q zA~QRrLV2v*nK1$-fG#rs3u}w>=`|RJ<6U_BCt3;2 zEEK=lNerC+U@Wa0EJ))xSsm+}2E)Mf6eM-nwTqzb+Ev*Z5s_}zs^0%6`K{W3B3=xq z2=7)BqvZ0b7QERofp^TVtH7ULC^`XrIreXro&x8U0_8amVilT@k6X4ZD&SUP+N4SkD+9530GOzNpN*mKCYzkea)JyZoWz#2epVBPvA zMM3E+snmi^@>yeRYm0?tW=0z^Z6(+lJt7}{|87a@D5W2?A#MG z^oI{<$6h+ce2)RK(BT_CvVX_-y7z2t7bJxI_Wtv6X=vBWjF2Oe0Vjl>vjcTB)n(Mx z9rhTl=0Z(>a$x@}^?eIHv;fZNYTAyAZ}pSn9x7e!H<&~t=uI4%6Yx66I@O%F2lb)(khvwpl2wj8IZg&c+nde)sY;L73 zPwVu$AQn>)o;>JhPfxcuO37KxisNRe9D0a|dH3aca@9`w0D^C6o@5MR7!vZ8@f43G zj>?pb%Fy~>A}__DUyWNYwE3RWty-h|Pc~_lw9sj$w?mYTS-F=Bx5t=dmOBC4tTp?% zOdN#FnFz6W6+>ode|{omr{$u(?u(N>d^n;>#90vNlwukzx)l<|5JM@~ zOEC)DGHc&*Qn;-Pfz|yOMVdo{-N^b>NH7SyzuWO z0n~@~7*l2qCH||;COPkVJWPRR1!8mYxVVE&kX@u`2b$wJS+p-@Og5Vv{!&gifDg7|ZN;x> z%8HyGX27;lM~k2ZD4i3rhE}wovLUWLKlap0vkd3QQ?&-tPaNCHPCRQ0o>JFfebQ=R z#2;A$%1!9n`HOJvnDR1U-d4k`Taw;>wI$8oS{#xqL2N)p&U{W6ivnAkI@xc&yS?@- z93kKFlI^_LSvYuC3~%gS3WpeyF!$0EFwShIS|<*rk}sCUN>>a;g5?^qC2~?dzXCwb z<(ANt3YvM!x_@)KFg$uVULBJCvQOL`ww$(khZeG;I3eYhDE~H@9k};~v zAXJ7cT@fyt0qXo|80UhDcZ$I-_d5eT?ZTc+$do=2;~tB=&s*0yBvz$`euw!@d8L7{ zM$%M6S#VunHy9e^q82&wohqyb7PK^%{AL@kw4H^|wlF{8q7O(Tis^>7X#*%BFz$-E zVgslkL*s_C!3tFTHT@ay02ur;YH_fcSzo(<_BfU+>xI8It;1b9 zKP)71;-TP6x~+RLF!Sd>DxQ_-jKlcg0RVht{$Dg4_kYrG0~crWf2FpQRc-9n84$jw zYyS2=@<#~rp%)>auP)o-BG1YwsSvWafh_0~e*j%+et#qdu{HY(yv-uLcV^Da;My4f zQx`_a+TPUn1tWA%9M#sFBS|Merv#0Ut{DHE%b1?qouZIpI1p&2Ue7YXOpr`ixv{kl zcKX8fN0+$|Ng1J6@g739qe&i0hT&Wf=Hp;&>E`ZG>jxfWwo{Cx82@uE;t!nV>JRs2 zYvqy3psni_iV5kRx&U)Oiz?{nldEvCp|G;u`{WC9L?BZsX{l?HCjCR?qLYs%)Wc(rFRT*5v>(sh?nWmq zE7ef@jLPH7-sx;3>X?WOS2SbeZe0%$zo9>^5gGeaaFJ)qL~A*-G1=Z4%n0qL-7N(p z;H@VOsU-fS?FT|NY;RCf2iiLVd43<3P$2#3=gj=B$=d+;h3#&UTce=$b>Xtd42+XM z#wnEKH;N!M0Fe{N6UJzuAtiuhRQvP4`Z)8bq}Mc#V_Gidl4iMHYp`4fv<8jbQ8P`l zLB$<&$rc@R-w{U?D=ltjYF_oKC^2d-rMRbAC@NWAC3kbVE{M@p^Lq7aF$2w^5S#h( z2Zw(?=lyZc`~IHuKF{|HiZihEAsv#?zA3V&_N7RfizMRJsXnx0L$|IjVrp0x%oxd# z$xr@0R>WM!m3pJW-h)|dJ31SNj$^EKmxX_r>r)|%FaxZ>bkwmcwk+F(q`AAUXmo@e zk#L{A0apfI>Cv!(Dh=wG123ke>z}RaZVw#k52)@5WIT*VGp@U9894M`8Z$CvqMAUy zHPHN*`NnIL#T_V^6 z?mIgb7^NCnCVNBEh(23<`KQ!p>G|_rsIzZqXvmadY|kfGwocpVG^;W{@z_ro826DVAR}E~{tvM19fHrQ>b{u>bz~Y$7WrE#dVKe^_pH z?W5HI={59Ysw7e6g{~%s$|PDVIt*Wg_r1?NApIs-LqXAuYD8VN5KpCnjN{WS6yM!? z^ICEVa*&}IwS{QEd(}Xyy;Oz3l9XObVITZeesBZW^CRTu1WXL_!Z!wDd|PCA-&I4| zQx;+p&*v@>hTVRQh@&KHmbg<6pA7{7VBrr6>@Uh8DFH<<9b^4)AC(@o#lwMjXtx>F7RoC}d!;wMyI7H^SVemsKSfgGQ^L$HgXhZ2n=DU~YR_X|} z#e2QPAH;2>rCvx;05-5`r}Yw*7H_Qq1*gsclgnyhphokcOI~303?UiqE7W2d)4O=D z#%KI`iKc~rffr-D&BbV@+Skm~9bPb$rPI?haRTzQhEv36-@|)MCPr zPn(2KAAL^gfC`kl6c&lY#n>+ zVWMlr7GOHrFOB;4me=C&b1lEW_^34I^lODBn}#OkAX5!O@+n4-a38xx_uGW$od*>^ z9T~9?T4eixQ4=k`5WU31s}gE~+A_a(IPJgIMZZsQ_?P?2dTJ$Qgcadg^LGfMb+k~& zuBNP6sXTiWOMkT{-F9Qa*e7~_bwPCEE4M7*_iHrKCIQWzjvZarAHN5Xf0z_x*SjAl+;XJV znA()Dqe^31N~mvtd0q8%sZ0Hdyd3gON9DLyF0w=T=n=+4my2u7@~ghn1<^uM@*|5^ zB;QA6R*)bS+CzVvYztytzaxGjuQmnj@IgE)pRBNQ+`2ANrriGwZk2!#pO2g}N~HwZ z+htuwTc=mHgWuqV(Pm5Dv@=n6v|$F5%<1ao+IjCjM%gm7d!QuyKj1@ZkDa}2rfT6uJ{+xLcG{=yR zfD7$06aL>pL7W5Yi^y2+*SF>xe{7H-Loh7mzXSk)jD>Md$nQj_@BqBL5q>W{H*bU| zBG#0%?5~U1kv_s>@Dh&%UH3c&85=Lo&-m)W=K;8j;QAK%9bsJGB2PptT81C+&Be%1 z;5x_n?F3xY08eDB5hovHpm&yVG-^*#E0{~K-&kSe#Y1nXo{Rc#@Iq?7h literal 0 HcmV?d00001 diff --git a/vscode-extension/package.json b/vscode-extension/package.json index 69a4fad..1ba04d5 100644 --- a/vscode-extension/package.json +++ b/vscode-extension/package.json @@ -2,7 +2,7 @@ "name": "beetask-vscode", "displayName": "BeeTask", "description": "Gerenciamento e rastreamento de tarefas com cronômetro integrado ao VS Code", - "version": "1.0.0", + "version": "1.1.0", "publisher": "beetech", "repository": { "type": "git", @@ -153,6 +153,16 @@ "type": "number", "default": 30, "description": "Intervalo de atualização automática das tarefas (em segundos)" + }, + "beetask.enableIdleDetection": { + "type": "boolean", + "default": true, + "description": "Ativar pausa automática da tarefa por inatividade no VS Code" + }, + "beetask.idleTimeoutMinutes": { + "type": "number", + "default": 10, + "description": "Tempo limite de inatividade em minutos para pausar a tarefa ativa (padrão: 10 minutos)" } } } diff --git a/vscode-extension/src/commands.ts b/vscode-extension/src/commands.ts index 28e15cd..eb19bf4 100644 --- a/vscode-extension/src/commands.ts +++ b/vscode-extension/src/commands.ts @@ -3,6 +3,7 @@ import { BeeTaskApiClient } from './api'; import { AuthManager } from './authManager'; import { StatusBarManager } from './statusBarManager'; import { TaskTreeProvider, TaskTreeItem } from './taskTreeProvider'; +import { IdleDetector } from './idleDetector'; import { Task } from './types'; export function registerCommands( @@ -10,7 +11,8 @@ export function registerCommands( api: BeeTaskApiClient, authManager: AuthManager, statusBar: StatusBarManager, - treeProvider: TaskTreeProvider + treeProvider: TaskTreeProvider, + idleDetector?: IdleDetector ): void { // 1. LOGIN context.subscriptions.push( @@ -56,7 +58,7 @@ export function registerCommands( } ); - await refreshAll(api, authManager, statusBar, treeProvider); + await refreshAll(api, authManager, statusBar, treeProvider, idleDetector); // Prompt org selection if multiple const orgs = authManager.getOrganizations(); @@ -109,7 +111,7 @@ export function registerCommands( if (selected) { await authManager.setActiveOrgId(selected.orgId); vscode.window.showInformationMessage(`Organização ativa alterada para: ${selected.label}`); - await refreshAll(api, authManager, statusBar, treeProvider); + await refreshAll(api, authManager, statusBar, treeProvider, idleDetector); } }) ); @@ -117,7 +119,7 @@ export function registerCommands( // 4. REFRESH TASKS context.subscriptions.push( vscode.commands.registerCommand('beetask.refreshTasks', async () => { - await refreshAll(api, authManager, statusBar, treeProvider); + await refreshAll(api, authManager, statusBar, treeProvider, idleDetector); vscode.window.setStatusBarMessage('BeeTask: Tarefas atualizadas.', 2000); }) ); @@ -155,7 +157,7 @@ export function registerCommands( try { await api.startTask(task.id); vscode.window.showInformationMessage(`▶️ Iniciada: #${task.id} ${task.title}`); - await refreshAll(api, authManager, statusBar, treeProvider); + await refreshAll(api, authManager, statusBar, treeProvider, idleDetector); } catch (err: any) { vscode.window.showErrorMessage(`Falha ao iniciar tarefa: ${err.message}`); } @@ -182,7 +184,7 @@ export function registerCommands( try { await api.stopTask(task.id); vscode.window.showInformationMessage(`⏸️ Pausada: #${task.id} ${task.title}`); - await refreshAll(api, authManager, statusBar, treeProvider); + await refreshAll(api, authManager, statusBar, treeProvider, idleDetector); } catch (err: any) { vscode.window.showErrorMessage(`Falha ao pausar tarefa: ${err.message}`); } @@ -215,7 +217,7 @@ export function registerCommands( try { await api.updateStatus(task.id, 'COMPLETED'); vscode.window.showInformationMessage(`✔️ Tarefa #${task.id} concluída com sucesso!`); - await refreshAll(api, authManager, statusBar, treeProvider); + await refreshAll(api, authManager, statusBar, treeProvider, idleDetector); } catch (err: any) { vscode.window.showErrorMessage(`Falha ao concluir tarefa: ${err.message}`); } @@ -279,7 +281,7 @@ export function registerCommands( }); vscode.window.showInformationMessage(`Tarefa #${created.id} criada com sucesso!`); - await refreshAll(api, authManager, statusBar, treeProvider); + await refreshAll(api, authManager, statusBar, treeProvider, idleDetector); const startNow = await vscode.window.showInformationMessage( `Deseja iniciar o cronômetro para #${created.id} agora?`, @@ -288,7 +290,7 @@ export function registerCommands( ); if (startNow === 'Sim, Iniciar') { await api.startTask(created.id); - await refreshAll(api, authManager, statusBar, treeProvider); + await refreshAll(api, authManager, statusBar, treeProvider, idleDetector); } } catch (err: any) { vscode.window.showErrorMessage(`Falha ao criar tarefa: ${err.message}`); @@ -361,7 +363,7 @@ export function registerCommands( }); vscode.window.showInformationMessage(`✨ Tarefa #${created.id} criada via IA!`); - await refreshAll(api, authManager, statusBar, treeProvider); + await refreshAll(api, authManager, statusBar, treeProvider, idleDetector); const startNow = await vscode.window.showInformationMessage( `Deseja iniciar o cronômetro para #${created.id}?`, @@ -370,7 +372,7 @@ export function registerCommands( ); if (startNow === 'Sim, Iniciar') { await api.startTask(created.id); - await refreshAll(api, authManager, statusBar, treeProvider); + await refreshAll(api, authManager, statusBar, treeProvider, idleDetector); } } catch (err: any) { vscode.window.showErrorMessage(`Falha na criação com IA: ${err.message}`); @@ -526,8 +528,10 @@ async function refreshAll( api: BeeTaskApiClient, authManager: AuthManager, statusBar: StatusBarManager, - treeProvider: TaskTreeProvider + treeProvider: TaskTreeProvider, + idleDetector?: IdleDetector ): Promise { + idleDetector?.recordActivity(); const isAuth = await authManager.isAuthenticated(); if (!isAuth) { statusBar.setActiveTask(null); diff --git a/vscode-extension/src/extension.ts b/vscode-extension/src/extension.ts index 3cb97dc..7606695 100644 --- a/vscode-extension/src/extension.ts +++ b/vscode-extension/src/extension.ts @@ -3,6 +3,7 @@ import { AuthManager } from './authManager'; import { BeeTaskApiClient } from './api'; import { StatusBarManager } from './statusBarManager'; import { TaskTreeProvider } from './taskTreeProvider'; +import { IdleDetector } from './idleDetector'; import { registerCommands } from './commands'; let pollTimer: NodeJS.Timeout | null = null; @@ -12,17 +13,19 @@ export async function activate(context: vscode.ExtensionContext): Promise const api = new BeeTaskApiClient(authManager); const statusBar = new StatusBarManager(); const treeProvider = new TaskTreeProvider(api, authManager); + const idleDetector = new IdleDetector(api, authManager, statusBar, treeProvider); - // Register Tree View + // Register Tree View & Status Bar & Idle Detector const treeView = vscode.window.createTreeView('beetask.tasksView', { treeDataProvider: treeProvider, showCollapseAll: true, }); context.subscriptions.push(treeView); context.subscriptions.push(statusBar); + context.subscriptions.push(idleDetector); // Register Commands - registerCommands(context, api, authManager, statusBar, treeProvider); + registerCommands(context, api, authManager, statusBar, treeProvider, idleDetector); // Initial Sync if (await authManager.isAuthenticated()) { diff --git a/vscode-extension/src/idleDetector.ts b/vscode-extension/src/idleDetector.ts new file mode 100644 index 0000000..c2d1361 --- /dev/null +++ b/vscode-extension/src/idleDetector.ts @@ -0,0 +1,168 @@ +import * as vscode from 'vscode'; +import { BeeTaskApiClient } from './api'; +import { AuthManager } from './authManager'; +import { StatusBarManager } from './statusBarManager'; +import { TaskTreeProvider } from './taskTreeProvider'; +import { Task } from './types'; + +export class IdleDetector implements vscode.Disposable { + private lastActivityTime: number = Date.now(); + private checkInterval: NodeJS.Timeout | null = null; + private isPrompting: boolean = false; + private disposables: vscode.Disposable[] = []; + + private api: BeeTaskApiClient; + private authManager: AuthManager; + private statusBar: StatusBarManager; + private treeProvider: TaskTreeProvider; + + constructor( + api: BeeTaskApiClient, + authManager: AuthManager, + statusBar: StatusBarManager, + treeProvider: TaskTreeProvider + ) { + this.api = api; + this.authManager = authManager; + this.statusBar = statusBar; + this.treeProvider = treeProvider; + + this.registerActivityListeners(); + this.startPeriodicCheck(); + } + + public recordActivity(): void { + this.lastActivityTime = Date.now(); + } + + private registerActivityListeners(): void { + // 1. Digitação ou alteração de código + this.disposables.push( + vscode.workspace.onDidChangeTextDocument(() => this.recordActivity()) + ); + + // 2. Movimentação de cursor ou seleção de texto + this.disposables.push( + vscode.window.onDidChangeTextEditorSelection(() => this.recordActivity()) + ); + + // 3. Troca de arquivo / aba ativa + this.disposables.push( + vscode.window.onDidChangeActiveTextEditor(() => this.recordActivity()) + ); + + // 4. Rolagem da página (scroll) + this.disposables.push( + vscode.window.onDidChangeTextEditorVisibleRanges(() => this.recordActivity()) + ); + + // 5. Salvamento de arquivo + this.disposables.push( + vscode.workspace.onDidSaveTextDocument(() => this.recordActivity()) + ); + + // 6. Janela do VS Code ganhou foco + this.disposables.push( + vscode.window.onDidChangeWindowState((state) => { + if (state.focused) { + this.recordActivity(); + } + }) + ); + } + + private startPeriodicCheck(): void { + // Checa a cada 15 segundos + this.checkInterval = setInterval(async () => { + await this.checkIdleStatus(); + }, 15000); + } + + private async checkIdleStatus(): Promise { + const config = vscode.workspace.getConfiguration('beetask'); + const enabled = config.get('enableIdleDetection', true); + const timeoutMinutes = config.get('idleTimeoutMinutes', 10); + + if (!enabled || timeoutMinutes <= 0) { + return; + } + + const activeTask = this.statusBar.getActiveTask(); + if (!activeTask) { + // Se não há tarefa rodando, mantém o relógio zerado para a próxima + this.lastActivityTime = Date.now(); + return; + } + + if (this.isPrompting) { + return; + } + + const idleMillis = Date.now() - this.lastActivityTime; + const idleMinutes = idleMillis / 60000; + + if (idleMinutes >= timeoutMinutes) { + await this.handleIdlePause(activeTask, timeoutMinutes); + } + } + + private async handleIdlePause(task: Task, timeoutMinutes: number): Promise { + this.isPrompting = true; + console.log(`[BeeTask] Inatividade de ${timeoutMinutes}min detectada. Pausando tarefa #${task.id}...`); + + try { + // 1. Pausa imediatamente a tarefa no servidor + await this.api.stopTask(task.id); + this.statusBar.setActiveTask(null); + this.treeProvider.refresh(); + + // 2. Pergunta ao usuário se ele ainda está trabalhando nela + const question = `Você ainda está trabalhando na tarefa #${task.id} - ${task.title}?`; + const choice = await vscode.window.showWarningMessage( + question, + { modal: false }, + 'Sim', + 'Não' + ); + + if (choice === 'Sim') { + // Usuário confirmou que ainda está trabalhando -> retoma a tarefa + await this.api.startTask(task.id); + vscode.window.showInformationMessage(`▶️ Tarefa #${task.id} retomada!`); + } else { + // Clicou "Não" ou fechou a notificação -> mantém pausada + vscode.window.showInformationMessage(`⏸️ Tarefa #${task.id} mantida pausada.`); + } + } catch (err: any) { + console.error('[BeeTask] Erro ao processar pausa por inatividade:', err); + } finally { + // Reinicia o relógio de atividade para não dar loop + this.recordActivity(); + this.isPrompting = false; + + // Sincroniza estado visual final + try { + const orgId = this.authManager.getActiveOrgId(); + const tasks = await this.api.listMyTasks(orgId); + let runningTask = null; + for (const t of tasks) { + if (t.history && t.history.some(h => h.startAt && !h.endAt)) { + runningTask = t; + break; + } + } + this.statusBar.setActiveTask(runningTask); + this.treeProvider.refresh(); + } catch (_) {} + } + } + + public dispose(): void { + if (this.checkInterval) { + clearInterval(this.checkInterval); + this.checkInterval = null; + } + this.disposables.forEach(d => d.dispose()); + this.disposables = []; + } +}