feat(extension): adicionar lembrete inteligente para iniciar tarefa ao codar sem task ativa
This commit is contained in:
parent
c613c71f1e
commit
e7703f34e7
4 changed files with 106 additions and 9 deletions
|
|
@ -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`).
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -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)"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<void> {
|
||||
const config = vscode.workspace.getConfiguration('beetask');
|
||||
const enabled = config.get<boolean>('enableNoActiveTaskPrompt', true);
|
||||
const cooldownMinutes = config.get<number>('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;
|
||||
|
|
|
|||
Loading…
Reference in a new issue