メモ帳？一時停止？そんなのいらん──こだわりしかないシンプルな集中タイマーを作った

## なぜ作ったか

ポモドーロアプリ、探せば山ほど出てきます。でもどれもしっくり来なかった。

* 多機能すぎて、もはやタスク管理ツールになっている
* シンプルすぎて、ただ25分と5分を回すだけ

「自分にちょうどいい」って意外とない。

求めていたのは以下の2点だけ：

* ポモドーロを“意識せずに”自然に使えること
* 自分に合ったテンプレートを保存して呼び出せること

この2つに全振りして、**Focus Wisp** を作りました。初のFlutterアプリです。

## アプリ概要

**Focus Wisp（Android対応）**
集中の流れを切らない、最小限の機能に絞ったポモドーロタイマー。

### できること

#### ポモドーロタイマー

* スタート／リセットのみ
* 一時停止なし（途中で集中切れるくらいなら最初からやり直せ、という方針）

#### テンプレート管理

* 作業ジャンルごとにタイマー設定を保存

  * 作業時間・休憩時間
  * 通知のオン／オフ
  * 今後：音楽／背景／テーマカラーなども追加予定

#### UIと体験

* シンプル設計で没入感重視
* Light/Dark モード対応
* ローカル通知対応

## 技術スタック
```text
Flutter
Firebase (Firestore, Crashlytics, App Distribution)
Riverpod
shared_preferences
flutter_local_notifications
timezone
logger
mocktail
```


## 設計の概要
### 関係図
```mermaid
graph TD
  Launch[アプリ起動] --> GuideBar[ガイドバー表示]

  GuideBar --> TimerTab[Timerタブ]
  GuideBar --> TemplateTab[Templateタブ]
  GuideBar --> HistoryTab[Historyタブ（未実装）]
  GuideBar --> SettingsTab[Settingsタブ]

  subgraph Timerタブ
    TimerTab --> SelectTemplate[テンプレート選択]
    TimerTab --> StartReset[スタート／リセット/状態変更]
  end

  subgraph Templateタブ
    TemplateTab --> NewTemplate[テンプレート新規作成]
    TemplateTab --> EditTemplate[テンプレート編集]
  end

  subgraph Settingsタブ
    SettingsTab --> NotifyToggle[通知 ON/OFF]
    SettingsTab --> ThemeToggle[ダーク／ライトモード切替]
  end

  %% 通知
  StartReset --> NotifyNormal[普通の通知更新]
  StartReset --> NotifyPersistent[常駐通知表示]

  %% SharedPreferences
  SharedPrefs[SharedPreferences]
  SharedPrefs -.-> TimerTab
  SharedPrefs -.-> TemplateTab
  SharedPrefs -.-> SettingsTab

```

### コアモデル設計
```mermaid
erDiagram
    LEARNING_TEMPLATE {
        Int id
        Int userId
        String templateName
        Int workDuration
        Int breakDuration
        Boolean enableNotification
        Date createdAt
        Date updatedAt
        Int displayOrder
    }

    TIMER {
        Int id
        String templateName
        Int workDuration
        Int breakDuration
        Boolean enableNotification
        Int longBreakDuration
        String startTime
        String endTime
        Int remainingSeconds
        Boolean isRunning
        String currentTerm
    }

    NOTIFICATION_MODEL {
        Int id
        String type
        Date scheduledAt
        Date createdAt
        String payload
        Boolean isCancelled
    }

    %% 一方向のデータフロー（論理的な生成・依存関係）
    LEARNING_TEMPLATE ||--o{ TIMER : provides
    TIMER ||--o{ NOTIFICATION_MODEL : triggers

```

## 開発の道のり

Flutterもモバイルアプリも未経験の状態からスタート。

1. React Native + Expo を試すも、依存ライブラリ周りで挫折
2. Flutterに切り替え、YouTubeとAI（ChatGPT / Claude / Copilot）をフル活用
3. 詰まったポイント：

   * Androidの通知とバックグラウンド制御
   * アーキテクチャ選定（Riverpod採用）
   * 変数設計、命名の整理
   * 外部APIやMockの切り分け（依存性注入の考え方）

## 今後の展望

やりたいことは山ほどある。

* 統計機能

  * 総作業時間、テンプレート別の使用傾向など
* Firebase Authでログイン機能
* Windows対応
* テンプレートごとの設定拡張

  * 音楽／環境音／背景／テーマカラー
* スマホとPC間のタイマー同期

  * PCアプリ起動と同時にタイマー開始
  * フォーカス切替でPush通知

## スクリーンUI

* タイマー画面のスクショ
<img width=150 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4032613/53a68549-8184-41ac-83ee-af3073c86fbc.png">

* テンプレート設定画面のスクショ
<img width=150 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4032613/01adda8f-c733-4e32-a2d5-cd5cee96d751.png">

* ダイアログ画面のスクショ
<img width=150 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4032613/061eabd4-58f2-4a5d-a4f5-0d1f653bb843.png">

## 最後に

まだアルファ版ですが、「自分に本当に必要だったもの」がようやく形になりました。
アプリ開発初心者でも二か月頑張ればそこそこの形のアプリを作ることができるんだなと実感しました。
すごい時代になったなと思います。

文章を読んでくださってありがとうございます。
この記事は私の書いた最初のQiita記事になります。
これからはアプリ開発で詰まったポイントやほかのアプリを開発しはじめたらまた記事を投稿しようと思います。

以下に私のアルファ版ポモドーロタイマーアプリFocus WispをApp distributionにて公開しているのでよろしければダウンロードお願いします。(Android限定です。またフィードバック機能は未実装です。なにかあればMailかQiita上で連絡をお願いします)

https://appdistribution.firebase.dev/i/b2d9606cf2f94284

## 参考資料
(この記事に関するものだけではなくアプリ作成の上で参考にさせていただいた資料になります）
#### Qiita

https://qiita.com/Qiita/items/c686397e4a0f4f11683d

https://qiita.com/squid-cat/items/e6bb159a3c2b30e3405f

https://qiita.com/kmatsushita1012/items/5478a0e10cf15d46279a

#### Zen

https://zenn.dev/music_shio/articles/ff094c28ce9286

https://zenn.dev/steelydylan/articles/expo-app-distribution

https://zenn.dev/flutteruniv/books/flutter-architecture

https://zenn.dev/heyhey1028/books/flutter-basics



#### Youtube
[【保存版】Flutterアーキテクチャー解説！MVVMのデメリットとは？](https://www.youtube.com/watch?v=jhUNGYowpoA)

[Flutter公式のYoutubeチャンネル](https://www.youtube.com/@flutterdev)