Skip to content

Pomodoro - Configure à sua maneira e utilize essa poderosa ferramenta para a sua produtividade

Notifications You must be signed in to change notification settings

marcelluscaio/Pomodoro

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

56 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Pomodoro

Ferramenta para auxiliar na aplicação do método Pomodoro. Controle seus ciclos de foco e descanso e aumente sua produtividade.

Acesse

Acesse a aplicação clicando aqui.

Construído com:

JavaScript TailwindCSS css3 html5

Funcionalidades

🛠️ Permanência de dados da configuração utilizando localStorage;
⚙️ Animação na engrenagem e na sidebar;
🧐 Sidebar criada com técnica de glassmorphism;
🔊 Aviso sonoro ao fim de cada ciclo;
🎨 Mudança de cor de fundo proporcional ao tempo decorrido;
⏱️ Cronômetro com 3 estágios: foco, pausa e descanso;
#️⃣ Contagem de ciclos concluídos;
🤖 Contador de tempo aparece na aba do navegador;
🖋️ Tipografia fluida

Técnicas para prestar atenção

Estrutura

O código estava estruturado em uma sequência de condicionais, o que dificultava a manutenção e mesmo o desenvolvimento em si do projeto. A criação de um objeto com as regras de cada etapa, e uma função que executa essas regras tornou o código mais legível e permitiu enxergar novas possibilidades de melhoria, como a criação da etapa "skip code". O código era assim (ainda em estágio intermediário de desenvolvimento):

if(controlButton.innerText==='START'){
      noticeToUser.innerText = "Concentre-se";
      controlButton.innerText = 'pause';
      timer.innerText = formatTime(timeLeft);
      cycleCount++;
      cycles.innerText = cycleCount;
      clearInterval(counter);
      clearTimeout(timeOut);
      counter = setInterval(() => {      
         
         
         bodyHue += rate;
         body.style.backgroundColor = `hsl(${bodyHue}, 50%, 25%)`;
         controlButton.style.backgroundColor = `hsl(${bodyHue}, 50%, 25%)`;    
         timeLeft--;
         timer.innerText = formatTime(timeLeft);
      }, "1000");

      setsCountdown();

   } else if(controlButton.innerText==='PAUSE'){
      noticeToUser.innerText = "Tempo pausado";
      controlButton.innerText = 'restart';      
      clearInterval(counter);
      clearTimeout(timeOut);

   } else if(controlButton.innerText==='RESTART'){
      noticeToUser.innerText = "Concentre-se";
      controlButton.innerText = 'pause';      

      counter = setInterval(() => {      
         bodyHue += rate;
         body.style.backgroundColor = `hsl(${bodyHue}, 50%, 25%)`;
         controlButton.style.backgroundColor = `hsl(${bodyHue}, 50%, 25%)`;   
         timeLeft--;
         timer.innerText = formatTime(timeLeft); 
      }, "1000");

      setsCountdown();
   
   } else if(controlButton.innerText==='REST'){
      noticeToUser.innerText = "Começou seu descanso";
      controlButton.innerText = 'start';
      let totalRestTime = cycleCount % 4 === 0 ? longerRestTime : restTime;
      let restTimeLeft = totalRestTime / 1000;
      timer.innerText = formatTime(restTimeLeft);
      counter = setInterval(() => {
         let restRate = 120/(totalRestTime/1000);
         bodyHue -= restRate;
         body.style.backgroundColor = `hsl(${bodyHue}, 50%, 25%)`;
         controlButton.style.backgroundColor = `hsl(${bodyHue}, 50%, 25%)`; 
         restTimeLeft--;
         timer.innerText = formatTime(restTimeLeft); 
      }, "1000");

      timeOut = setTimeout(() => {      
         console.log("Acabou o Descanso!");
         clearInterval(counter);
         noticeToUser.innerText = "Seu descanso acabou. Comece mais um foco"
      }, restTimeLeft * 1000);
   }
function setsCountdown(){
   timeOut = setTimeout(() =>
      {
         clearInterval(counter);
         noticeToUser.innerText = "Seu Pomodoro acabou. Descanse um pouco";
         controlButton.innerText = 'rest';
         timeLeft = totalTime / 1000;
      }, timeLeft * 1000);
} 

E foi estruturado como pode ser visto no arquivo pomodoroEngine.js.

White-space

A seção de mensagem ao usuário, ainda que vazia, ocupa espaço na tela, permitindo uma quantidade menor de mudança de layout. Para isso utilizei a propriedade white-space com o valor pre-wrap (a classe utilitária whitespace-pre-wrap no Tailwind).

Input text só aceita números

Utilização de input text para os valores numéricos da configuração, tendo em vista os problemas que o input number pode trazer (ver: https://css-tricks.com/what-to-use-instead-of-number-inputs/ ). Para lidar com isso, criei uma validação que impede o usuário de inserir qualquer caracter não numérico:

const allowOnlyNumbers = value => value.replace(/[^0-9]+/, '');

Havia utilizado outra forma de checar se um valor era uma letra, mas símbolos e acentos não eram identificados

const isLetter = (character) => character.toLowerCase() != character.toUpperCase();

Mudança de cores de fundo

A mudança de cores do fundo havia sido estruturada da seguinte forma:

let percentageOfInterval = 100 - (((timeLeft*1000) / totalTime) * 100);
bodyHue = percentageOfInterval *1.2; 

Isso funcionava para partir do Hue 0, mas não funcionava para retornar para o ponto inicial. Reestruturei o código utilizanto uma taxa e direção, o que permite lidar com situações como a volta à cor inicial, no caso da etapa 'break' e permitir que a cor final seja sempre a mesma em casos de pausa (em uma etapa do desenvolvimento a pausa reiniciava a mudança de cor, fazendo com que a cor de fundo variasse de acordo com a quantidade de pausas que o usuário fazia):

function changesBg(rate, direction){   
   direction === 'forward' ? bodyHue += rate : bodyHue -= rate;
   body.style.backgroundColor = `hsl(${bodyHue}, 50%, 25%)`;
   controlButton.style.backgroundColor = `hsl(${bodyHue}, 50%, 25%)`;
}

Precisei ainda criar uma animação que restabelece de forma gradativa a cor de fundo caso o usuário resolva pular o descanso ('skip rest'):

.restore{
   animation-name: backToRed;
   animation-duration: 1.5s;
   animation-timing-function: ease-in-out;
   animation-direction: normal;
   animation-fill-mode: forwards;
}

@keyframes backToRed{
   to{
      background-color: hsl(0, 50%, 25%)
   }
}

Interação entre sidebar e funcinalidade principal

Criei um mecanismo para impedir que o temporizador funcione quando o menu de configurações lateral é aberto.

const handlePomodoroButton = () => {
   switch(controlButton.innerText){
      case 'START':
         break;
      case 'PAUSE':
         pomodoroEngine('PAUSE')
         break;
      case 'RESTART':
         !sidebarIsOpen && pomodoroEngine('RESTART')
         //Prevents pomodoro from restarting when user had paused it before opening configs, and having the time reunning while user was in configs
         break;
   }
}

Operadores ternários e short-circuit evaluation

Utilização de operadores ternários e short-circuit evaluation para trazer mais concisão e legibilidade para o código.

const toggleTranslate = () => {
   sidebar.classList.toggle('translate-x-full');
   sidebarIsOpen ? sidebarIsOpen = false : sidebarIsOpen = true;
}
saveButton.addEventListener('click', e => {
   e.preventDefault();
   setDurations();
   controlButton.innerText==="RESTART" && cycleCount--; //if configs ae saved during a cycle, decreases cycle count before increasing in pomodoroEngine
   handleSidebar(gear);
   pomodoroEngine('START');
});

Objetivo

O objetivo deste projeto foi desenvolver um sistema do Pomodoro em equipe durante o evento Live CoDe.

Tarefas

  • Create timeout
  • Create Pomodoro activator
  • Conect Pomodoro activator through JS
  • Create total time controler
  • Create countdown per second
  • Calculate remaining time
  • Create timer element on screen
  • Make timer change according to countdown
  • Control time, and after 25 minutes let user know time is out
  • Button to pause and get back
  • Button for interval
  • Show count of cycles
  • After 4, long pause
  • Change bg color according to mode
  • Change happens gradually
  • Style with Tailwind
  • Create Pomodoro Engine
  • Gear icon to open modal to setting
  • Animate gear
  • Style form as sidebar
  • Style input in form
  • Set time with input
  • When hit save sidebar goes away
  • When hit save pomodoro restarts
  • When engine is hit, pomodoro pauses
  • Update tab title with timer
  • Setting fluid typography
  • Disable button when sidebaer shows
  • Restart cycle when hitting save
  • Prevent pomodoro from restarting when user had paused it before opening configs
  • Save setting to local Storage
  • Setting timer on start dinamically
  • Sound at end of cycles
  • JS Organization

Screenshots

About

Pomodoro - Configure à sua maneira e utilize essa poderosa ferramenta para a sua produtividade

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published