Skip to content

az860917/focusflow

Repository files navigation

FocusFlow 🍅

番茄鐘計時器 × 任務管理器 — 專為開發者打造的生產力工具

React Vite PWA License

📸 Demo

FocusFlow Screenshot


✨ 功能總覽

⏱ 計時器

  • 四種模式:專注(25分)、短休息(5分)、長休息(15分)、自訂(精確到秒)
  • SVG 圓形進度環 + 頁面頂部進度條,雙重視覺呈現
  • 倒數結束後按「開始」自動重設並重新倒數

🔔 鬧鐘提醒

  • 計時結束後持續循環播放,直到手動關閉
  • 計時器跳出脈衝動畫橫幅,提示對應模式訊息
  • 5 種鈴聲可選,設定內支援即時試聽
鈴聲 描述
🔔 經典三音 三音階上升
🎵 清脆鐘聲 餘韻悠長
🤖 電子嗶嗶 四連電子音
✨ 空靈風鈴 四音漸升
🪘 禪意深鐘 低沉厚重

✅ 任務管理

  • 新增、刪除、完成任務,優先度三段(高 / 中 / 低)
  • 點擊任務設為當前專注目標,顯示於計時器中央
  • HTML5 原生拖拉排序,無外部套件依賴
  • 每個任務自動累積完成番茄數 🍅

🏷 標籤系統

  • 新增任務時可附加多個標籤(工作、學習、設計、開發…)
  • 支援自訂標籤,不受預設限制
  • 任務清單上方標籤篩選 bar,一鍵過濾

📊 專注統計

  • 今日番茄數 / 本週番茄數 / 單日最高 三張數字卡
  • 長條圖顯示近 7 天每日番茄數(Recharts)
  • 標籤分布橫條圖,一眼看出時間花在哪裡
  • 今日 / 本週切換視圖

🌓 深色 / 淺色模式

  • 右上角一鍵切換,全畫面平滑過渡
  • 偏好設定自動儲存

📲 PWA 支援

  • 可安裝至手機或桌面,像原生 App 使用
  • 完整離線快取,無網路也能正常使用
  • 首次訪問時自動顯示安裝提示橫幅

💾 localStorage 持久化

關掉頁面再打開,以下全部保留:任務清單、計時剩餘時間、今日番茄、統計紀錄、標籤、鈴聲偏好、主題。


🛠 技術棧

技術 用途
React 18 核心框架,Function Component
Vite 5 開發環境與打包
vite-plugin-pwa Service Worker 與 PWA manifest 自動生成
Recharts 統計圖表
Web Audio API 瀏覽器原生音效合成,零音效檔
HTML5 Drag & Drop API 原生拖拉排序,零套件
localStorage 資料持久化
SVG + CSS Animation 圓形進度環動畫

💡 技術亮點

setInterval + useRef 解決 closure 陷阱

// 直接在 setInterval callback 裡讀 state 會拿到舊值
// 改用 ref 確保永遠是最新狀態
const isRingingRef = useRef(false);

const stopAlarm = useCallback(() => {
  clearInterval(alarmIntervalRef.current);
  isRingingRef.current = false;  // ← ref 即時更新
  setIsRinging(false);
}, []);

alarmIntervalRef.current = setInterval(() => {
  if (!isRingingRef.current) {   // ← 不會讀到 stale closure
    clearInterval(alarmIntervalRef.current);
    return;
  }
  RINGTONES[ringRef.current]?.play(playTone);
}, interval);

Web Audio API 零音效檔合成

const playTone = useCallback((freq, dur, type = "sine", gain = 0.3) => {
  const ctx = new AudioContext();
  const osc = ctx.createOscillator();
  const gn  = ctx.createGain();
  osc.connect(gn);
  gn.connect(ctx.destination);
  osc.type = type;
  osc.frequency.setValueAtTime(freq, ctx.currentTime);
  gn.gain.exponentialRampToValueAtTime(0.001, ctx.currentTime + dur);
  osc.start(ctx.currentTime);
  osc.stop(ctx.currentTime + dur);
}, []);

原生 HTML5 拖拉排序(無套件)

const handleDrop = (e, targetId) => {
  const result  = [...tasks];
  const fromIdx = result.findIndex(t => t.id === dragId);
  const toIdx   = result.findIndex(t => t.id === targetId);
  const [moved] = result.splice(fromIdx, 1);
  result.splice(toIdx, 0, moved);
  setTasks(result);
};

SVG 圓形進度環

const circumference   = 2 * Math.PI * radius;
const strokeDashoffset = circumference * (1 - progress);

<circle
  strokeDasharray={circumference}
  strokeDashoffset={strokeDashoffset}
  style={{ transition: "stroke-dashoffset 0.9s linear" }}
/>

PWA 安裝提示

useEffect(() => {
  const handler = (e) => {
    e.preventDefault();      // 阻止預設提示
    setInstallPrompt(e);     // 儲存事件,稍後自訂時機觸發
    setShowInstallBanner(true);
  };
  window.addEventListener("beforeinstallprompt", handler);
  return () => window.removeEventListener("beforeinstallprompt", handler);
}, []);

🚀 本地啟動

git clone https://github.com/az860917/focusflow.git
cd focusflow
npm install
npm run dev

瀏覽器前往 http://localhost:5173

打包部署

npm run build     # 產生 dist/

推薦部署到 Vercel(直接連 GitHub repo 即可,零設定)。


📁 專案結構

focusflow/
├── public/
│   ├── icon-192.png     # PWA 圖示(需自行準備)
│   └── icon-512.png     # PWA 圖示(需自行準備)
├── src/
│   ├── App.jsx          # 主元件(所有邏輯與 UI)
│   └── main.jsx         # 應用程式入口
├── index.html
├── vite.config.js       # Vite + PWA 設定
└── package.json

安裝 PWA 套件

npm install vite-plugin-pwa -D

📄 License

MIT © 2025 林冠宇

About

番茄鐘計時器 × 任務管理器|React · PWA · Web Audio API

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors