UNPKG

pomo-tui

Version:

> A beautiful terminal-based Pomodoro timer built with React Ink

102 lines (101 loc) 4.49 kB
import React, { useState } from 'react'; import { Box, Text, useInput } from 'ink'; import TextInput from 'ink-text-input'; import SelectInput from 'ink-select-input'; import { Timer } from './timer.js'; export function Pomodoro({ onActiveChange }) { const [inputValue, setInputValue] = useState(''); const [sessionName, setSessionName] = useState(''); const [sessionDuration, setSessionDuration] = useState(null); const [activeSession, setActiveSession] = useState(null); const [callbackList, setCallbackList] = useState([]); const handleNameChange = (value) => { setInputValue(value); }; const handleNameSubmit = (value) => { if (value.trim()) { setSessionName(value.trim()); setInputValue(''); } }; const startSession = (duration) => { const breakDuration = duration === 25 ? 5 : 10; setSessionDuration(duration); setActiveSession({ name: sessionName, sessionDuration: duration, breakDuration, remainingTime: duration * 60, isBreak: false, }); onActiveChange(true); }; useInput(input => { if (sessionName && !sessionDuration) { if (input === 'i') { startSession(25); } else if (input === 'j') { startSession(50); } } }); const handlePause = (remainingTime) => { if (activeSession) { setCallbackList([...callbackList, { ...activeSession, remainingTime }]); setActiveSession(null); onActiveChange(false); } }; const handleSessionComplete = () => { if (activeSession) { setActiveSession({ ...activeSession, remainingTime: activeSession.breakDuration * 60, isBreak: true, }); } }; const handleBreakComplete = () => { setActiveSession(null); setSessionName(''); setSessionDuration(null); onActiveChange(false); }; const handleSessionResume = (session) => { setActiveSession(session); setCallbackList(callbackList.filter(s => s.name !== session.name)); onActiveChange(true); }; if (activeSession) { return (React.createElement(Box, { flexDirection: "column", alignItems: "center" }, React.createElement(Text, null, activeSession.name, " -", ' ', activeSession.isBreak ? 'Break Time' : 'Focus Time'), React.createElement(Timer, { initialSeconds: activeSession.remainingTime, onPause: handlePause, onComplete: activeSession.isBreak ? handleBreakComplete : handleSessionComplete, onActiveChange: onActiveChange, isCountdown: true }), activeSession.isBreak && React.createElement(Text, null, "Time for a break!"))); } return (React.createElement(Box, { flexDirection: "column", alignItems: "center" }, !sessionName && (React.createElement(Box, { flexDirection: "column", alignItems: "center" }, React.createElement(Text, null, "Enter session name and press Enter:"), React.createElement(TextInput, { value: inputValue, onChange: handleNameChange, onSubmit: handleNameSubmit }))), sessionName && !sessionDuration && (React.createElement(Box, { flexDirection: "column", alignItems: "center" }, React.createElement(Text, null, "Select session duration:"), React.createElement(Text, null, "Press ", React.createElement(Text, { color: "blue" }, "i"), " for 25 minutes (5 min break)"), React.createElement(Text, null, "Press ", React.createElement(Text, { color: "blue" }, "j"), " for 50 minutes (10 min break)"))), callbackList.length > 0 && (React.createElement(Box, { flexDirection: "column", marginTop: 1 }, React.createElement(Text, null, "Callback List:"), React.createElement(Box, null, React.createElement(SelectInput, { items: callbackList.map(session => ({ label: `${session.name} (${Math.floor(session.remainingTime / 60)}:${String(session.remainingTime % 60).padStart(2, '0')})`, value: session, })), onSelect: item => handleSessionResume(item.value) })))))); }