← ver outras postagens

Pelmodoro - um aplicativo para pomodoro feito em Elm

25/07/2021

Pelmodoro é um aplicativo para te ajudar a aplicar a técnica pomodoro no seu dia a dia. Se você ainda não conhece, vale a pena ler sobre na Wikipedia.

Pelmodoro Já existem diversos aplicativos para pomodoro, dos mais variados tipos e complexidades. Depois de alguma experiência com aplicativos diferentes, eu resolvi tentar fazer o meu próprio e Pelmodoro é o resultado.

Além do timer normal, que existe em todo aplicativo para pomodoro, coloquei alguns outros recursos:

Além disso Pelmodoro é um PWA off-line first o que significa que você pode instalá-lo no seu celular ou até mesmo no desktop. Eu tenho o usado como uma aplicação independente usando o suporte a PWAs do Edge.

Pelmodoro com temas Pelmodoro rodando como um PWA no desktop e alguns dos temas que podem ser usados

O projeto é totalmente open-source e você pode dar uma olhada no código no GitHub.

Por que criar mais um aplicativo para pomodoro?

Não existe só um motivo, e a resposta poderia ser simplesmente porque eu quis 😁 Mas além da vontade de criar algo, eu queria usar Elm, uma linguagem que tenho usado diariamente pelo último ano e meio, mas que nunca tinha criado algo do zero e totalmente meu.

Além disso eu vinha usando o Habitica (uma espécie de jogo RPG que tenta te ajudar a cumprir seus objetivos) para acompanhar minha produtividade e tarefas do dia a dia, mas sentia que era um tiro de canhão para o que eu precisava. A ideia, principalmente ao desenvolver o sistema de avaliação dos rounds, foi substituir o Habitica integrando os recursos que faziam sentido pra mim num aplicativo para pomodoro.

Calendário com estatísticas O calendário das estatísticas também serve como gráfico mostrando seus dias mais produtivos, inspirando no gráfico do GitHub

Fazendo funcionar

A principal ferramenta que usei pra criar a aplicação foi a linguagem Elm e seu ecossistema, que não é muito extenso, mas que oferece muita qualidade e me surpreendeu durante o desenvolvimento.

Elm é uma linguagem funcional, fortemente tipada e pura (com efeitos colaterais controlados) voltada para a criação de front-ends e, apesar de não ser uma linguagem extremamente popular, foi tranquilizador ver que muitos dos problemas que eu precisava resolver já haviam sido solucionados.

Para alguns outros recursos, não tive opção a não ser apelar para o JavaScript em si, principalmente na integração com o Spotify. Por sorte o Spotify tem uma documentação razoavelmente completa sobre como utilizar sua API. Depois de um pouco de problemas lutando com o esquema de autorização usando PKCE, implementar a integração foi bem tranquilo.

Além disso, para persistir o estado do aplicativo fiz uso tanto do localStorage (para as preferências e o estado do timer), quanto do IndexedDB (para salvar as estatísticas de uso). Ao invés de usar a API do IndexedDB diretamente, utilizei a excelente biblioteca Dexie que abstrai grande parte das complexidades de lidar com IndexedDB.

Para executar os sons de notificação usei a lib howler.js.

Avaliação dos rounds Avalie cada round de trabalho e verifique suas estatísticas

Tornando belo

Depois de me sentir satisfeito com os recursos implementados e a maneira como tudo estava funcionando, mostrei o trabalho para algumas pessoas que me deram feedbacks muito importantes, principalmente a respeito da estrutura do meu código. Em um período de aproximadamente 2 dias eu reescrevi a estrutura da aplicação refatorando a arquitetura quase que por completo. Ao final eu tinha um PR com a adição de 5.934 linhas e a remoção de 3.756.

Em um projeto deste tamanho, escrito totalmente em JavaScript, este seria um PR assustador, mas como ele foi feito com Elm, eu tinha garantias de que o meu código estava correto e compilando normalmente, o que me deu a tranquilidade de fazer o merge do PR sem pensar duas vezes.

A estrutura original do código foi sendo construída organicamente conforme os recursos iam sendo desenvolvidos, o que gerou um código funcional mas às vezes mal organizado e usando alguns anti-patterns. Um exemplo destes anti-patterns foi a separação dos módulos Model, Msg e Types. A ideia em separar estes módulos foi de evitar importações cíclicas, mas o que ela acabou demonstrando foram falhas na organização do meu código.

Usando o código da aplicação Real World, pude ver como é possível organizar melhor os módulos em partes separadas onde cada uma implementa o seu próprio loop de MVU (model-view-update), mantendo o módulo Main.elm como um hub que agrega cada "página" da aplicação.

A minha função update original era gigantesca, mas depois pude separar as mensagens para cada página mantendo o código mais organizado, contido e fácil de entender.

Dá pra falar muita coisa sobre padrões de estrutura de código em Elm mas recomendo a leitura do Elm patterns para uma visão mais geral dos principais padrões.

Além da reestruturação da aplicação, eu acabei implementando algumas decisões mais estilísticas para trazer algum senso de padronização pro código e que eu acho, pessoalmente, que tem seus benefícios:

Na maioria dos casos estas decisões foram tomadas pra tornar o código mais explícito, deixando claro de onde estão vindo as funções e tipos que estão sendo utilizados e quais são os seus efeitos.

Horas mais produtivas Estatísticas mensais, incluindo seus horários de trabalho mais produtivos

Pensamentos finais

Apesar da refatoração grande que fiz, sei que a estrutura ainda poderia melhorar em vários lugares, mas eu quero dar este projeto como finalizado. Eu sinto que software é algo que nunca está realmente pronto, tirando algumas jóias raras, mas eu preciso parar de colocar tanto tempo neste projeto que já funciona muito bem e supre as minhas necessidades e me afundar em algum outro projeto paralelo que vai consumir todo meu tempo livre 🤡

No geral eu estou muito satisfeito com o resultado final e tenho usado o aplicativo diariamente. Com sorte, o aplicativo também será útil para outras pessoas e se este for o seu caso eu vou ficar extremamente feliz se você me contar depois 😊