diff --git a/vscode-extension/README.md b/vscode-extension/README.md index 4ce2879..151ba3c 100644 --- a/vscode-extension/README.md +++ b/vscode-extension/README.md @@ -8,6 +8,7 @@ Extensão oficial do **BeeTask** para o Visual Studio Code. Gerencie suas demand - **⏱️ 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. +- **💡 Lembrete de Início de Tarefa:** Se você começar a editar código sem nenhuma tarefa ativa, a extensão lembra de forma sutil e pergunta qual tarefa você vai trabalhar. - **📋 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. @@ -81,3 +82,5 @@ Acesse `Configurações` (`Ctrl+,`) e busque por `BeeTask`: - `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`). +- `beetask.enableNoActiveTaskPrompt`: Lembrar de iniciar tarefa ao começar a codar (Padrão: `true`). +- `beetask.noActiveTaskCooldownMinutes`: Intervalo mínimo entre lembretes em minutos (Padrão: `15`). diff --git a/vscode-extension/beetask-vscode-1.1.0.vsix b/vscode-extension/beetask-vscode-1.2.0.vsix similarity index 83% rename from vscode-extension/beetask-vscode-1.1.0.vsix rename to vscode-extension/beetask-vscode-1.2.0.vsix index 04eb334..aef598e 100644 Binary files a/vscode-extension/beetask-vscode-1.1.0.vsix and b/vscode-extension/beetask-vscode-1.2.0.vsix differ diff --git a/vscode-extension/package.json b/vscode-extension/package.json index f9cd646..c11ae9d 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.1.0", + "version": "1.2.0", "publisher": "beetech", "icon": "media/icon.png", "repository": { @@ -163,6 +163,16 @@ "type": "number", "default": 10, "description": "Tempo limite de inatividade em minutos para pausar a tarefa ativa (padrão: 10 minutos)" + }, + "beetask.enableNoActiveTaskPrompt": { + "type": "boolean", + "default": true, + "description": "Lembrar de iniciar uma tarefa ao começar a codar sem nenhuma tarefa ativa" + }, + "beetask.noActiveTaskCooldownMinutes": { + "type": "number", + "default": 15, + "description": "Intervalo mínimo em minutos entre lembretes de início de tarefa (padrão: 15 minutos)" } } } diff --git a/vscode-extension/src/idleDetector.ts b/vscode-extension/src/idleDetector.ts index c2d1361..1577a05 100644 --- a/vscode-extension/src/idleDetector.ts +++ b/vscode-extension/src/idleDetector.ts @@ -11,6 +11,11 @@ export class IdleDetector implements vscode.Disposable { private isPrompting: boolean = false; private disposables: vscode.Disposable[] = []; + // Lembrete de codar sem tarefa ativa + private lastNoActivePromptTime: number = 0; + private isPromptingNoActive: boolean = false; + private pendingActivityTimer: NodeJS.Timeout | null = null; + private api: BeeTaskApiClient; private authManager: AuthManager; private statusBar: StatusBarManager; @@ -31,46 +36,121 @@ export class IdleDetector implements vscode.Disposable { this.startPeriodicCheck(); } - public recordActivity(): void { + public recordActivity(isCodeEdit: boolean = false): void { this.lastActivityTime = Date.now(); + + if (isCodeEdit) { + this.scheduleNoActiveTaskCheck(); + } } private registerActivityListeners(): void { - // 1. Digitação ou alteração de código + // 1. Digitação ou alteração de código (edição real de código) this.disposables.push( - vscode.workspace.onDidChangeTextDocument(() => this.recordActivity()) + vscode.workspace.onDidChangeTextDocument((e) => { + // Ignora alterações em esquemas que não sejam arquivos reais (ex: output, git, etc) + if (e.document.uri.scheme === 'file') { + this.recordActivity(true); + } else { + this.recordActivity(false); + } + }) ); // 2. Movimentação de cursor ou seleção de texto this.disposables.push( - vscode.window.onDidChangeTextEditorSelection(() => this.recordActivity()) + vscode.window.onDidChangeTextEditorSelection(() => this.recordActivity(false)) ); // 3. Troca de arquivo / aba ativa this.disposables.push( - vscode.window.onDidChangeActiveTextEditor(() => this.recordActivity()) + vscode.window.onDidChangeActiveTextEditor(() => this.recordActivity(false)) ); // 4. Rolagem da página (scroll) this.disposables.push( - vscode.window.onDidChangeTextEditorVisibleRanges(() => this.recordActivity()) + vscode.window.onDidChangeTextEditorVisibleRanges(() => this.recordActivity(false)) ); // 5. Salvamento de arquivo this.disposables.push( - vscode.workspace.onDidSaveTextDocument(() => this.recordActivity()) + vscode.workspace.onDidSaveTextDocument((doc) => { + if (doc.uri.scheme === 'file') { + this.recordActivity(true); + } else { + this.recordActivity(false); + } + }) ); // 6. Janela do VS Code ganhou foco this.disposables.push( vscode.window.onDidChangeWindowState((state) => { if (state.focused) { - this.recordActivity(); + this.recordActivity(false); } }) ); } + private scheduleNoActiveTaskCheck(): void { + if (this.pendingActivityTimer) return; + + // Aguarda 3 segundos de digitação contínua para exibir o lembrete de forma suave + this.pendingActivityTimer = setTimeout(async () => { + this.pendingActivityTimer = null; + await this.checkNoActiveTask(); + }, 3000); + } + + private async checkNoActiveTask(): Promise { + const config = vscode.workspace.getConfiguration('beetask'); + const enabled = config.get('enableNoActiveTaskPrompt', true); + const cooldownMinutes = config.get('noActiveTaskCooldownMinutes', 15); + + if (!enabled || this.isPromptingNoActive || this.isPrompting) { + return; + } + + const isAuth = await this.authManager.isAuthenticated(); + if (!isAuth) { + return; + } + + const activeTask = this.statusBar.getActiveTask(); + if (activeTask) { + // Já está com uma tarefa rodando, nada a fazer + return; + } + + const now = Date.now(); + if (now - this.lastNoActivePromptTime < cooldownMinutes * 60000) { + return; // Ainda dentro do período de cooldown + } + + this.isPromptingNoActive = true; + this.lastNoActivePromptTime = now; + + try { + const choice = await vscode.window.showInformationMessage( + '🐝 BeeTask: Você começou a mexer no código sem nenhuma tarefa ativa. Qual demanda você está trabalhando?', + 'Selecionar Tarefa', + 'Criar Nova Tarefa', + 'Lembrar mais tarde' + ); + + if (choice === 'Selecionar Tarefa') { + await vscode.commands.executeCommand('beetask.startTask'); + } else if (choice === 'Criar Nova Tarefa') { + await vscode.commands.executeCommand('beetask.createTask'); + } + } catch (err: any) { + console.error('[BeeTask] Erro ao exibir lembrete de tarefa ativa:', err); + } finally { + this.isPromptingNoActive = false; + } + } + private startPeriodicCheck(): void { // Checa a cada 15 segundos this.checkInterval = setInterval(async () => { @@ -158,6 +238,10 @@ export class IdleDetector implements vscode.Disposable { } public dispose(): void { + if (this.pendingActivityTimer) { + clearTimeout(this.pendingActivityTimer); + this.pendingActivityTimer = null; + } if (this.checkInterval) { clearInterval(this.checkInterval); this.checkInterval = null;