ponshu-room-lite/docs/phase4_implementation_plan.md

409 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Phase 4: ユーザビリティ向上 - 実装計画
**Version:** 1.0
**Date:** 2026-01-16
**Based on:** Antigravity's proposal + Claude's improvements
**Status:** Ready to implement
---
## Overview
Phase 4では以下2つの機能を実装します
1. 🌙 **ダークモード自動切替** - 時間帯に応じた自動テーマ変更
2. 🖋️ **和風フォント対応** - 日本酒アプリにふさわしいフォント選択
---
## Feature 1: ダークモード自動切替 🌙
### 要件定義
- **既存**: ライト/ダーク/システム連動の3モード
- **追加**: 時間連動モード(夜間自動ダーク化)
- **切替時刻**: 20:00〜06:00 = ダークモード
- **ユーザー設定**: 設定画面で選択可能
### 技術仕様
#### A. ThemeMode拡張
```dart
enum AppThemeMode {
light, // 常にライト
dark, // 常にダーク
system, // OSに従う
autoTime, // 時間連動(新規)
}
```
#### B. 時刻判定ロジック
```dart
class ThemeProvider extends ChangeNotifier {
AppThemeMode _themeMode = AppThemeMode.autoTime;
// 現在適用すべきThemeModeを計算
ThemeMode get effectiveThemeMode {
if (_themeMode == AppThemeMode.autoTime) {
final hour = DateTime.now().hour;
// 20:00〜06:00 = ダークモード
return (hour >= 20 || hour < 6) ? ThemeMode.dark : ThemeMode.light;
}
// その他のモードは既存ロジック
return _themeModeToFlutterThemeMode(_themeMode);
}
}
```
#### C. 自動更新メカニズム
**方式1: WidgetsBindingObserver推奨**
- アプリがバックグラウンドから復帰した時に再計算
- 電池消費が少ない
- リアルタイム性は低い(アプリを開いた時のみ)
**方式2: Timer**
- 1分ごとに時刻をチェック
- リアルタイム性が高い
- 電池消費がやや増える
**採用: 方式1推奨** - 日本酒アプリでは厳密なリアルタイム性は不要
```dart
class ThemeProvider extends ChangeNotifier with WidgetsBindingObserver {
@override
void didChangeAppLifecycleState(AppLifecycleState state) {
if (state == AppLifecycleState.resumed) {
// アプリ復帰時にテーマを再計算
notifyListeners();
}
}
}
```
#### D. UI実装
**設定画面の選択肢:**
```
○ ライトモード
○ ダークモード
○ システム設定に従う
● 自動(夜間ダーク) ← NEW
```
**現在の状態表示:**
```
テーマ: 自動(夜間ダーク)
現在: ダークモード20:00〜06:00適用中
```
### 実装ファイル
| ファイル | 変更内容 |
|---------|---------|
| `lib/providers/theme_provider.dart` | AppThemeMode enum追加、autoTime実装 |
| `lib/screens/settings_screen.dart` | 4つ目の選択肢追加、状態表示追加 |
| `lib/services/hive_service.dart` | autoTimeモードの永続化対応 |
### テスト計画
**1. 時刻判定テスト**
```dart
// テスト用時刻注入
class TimeService {
static DateTime Function() now = () => DateTime.now();
}
// テストケース:
// 05:59 → ダーク
// 06:00 → ライト
// 19:59 → ライト
// 20:00 → ダーク
```
**2. UI動作テスト**
- [ ] 設定で「自動(夜間ダーク)」を選択できる
- [ ] 現在の適用状態が表示される
- [ ] アプリ再起動後も設定が保持される
- [ ] 時刻をまたいでアプリを開くとテーマが変わる
**3. パフォーマンステスト**
- [ ] 電池消費が増えていない
- [ ] アプリ復帰時の遅延がない
---
## Feature 2: 和風フォント対応 🖋️
### 要件定義
- **既存**: システムフォントNoto Sans JP相当
- **追加**: 日本酒らしい和風フォント
- **実装方式**: Google Fonts動的読み込み
- **ユーザー設定**: 設定画面で選択可能
### フォント候補
#### Option 1: Potta One推奨 - Antigravity提案
- **特徴**: 丸みがあり親しみやすい、読みやすい
- **サイズ**: ~2MB
- **用途**: メイン表示、カジュアルな雰囲気
- **プレビュー**: ぽんしゅルーム / 純米大吟醸
#### Option 2: Yuji Syuku
- **特徴**: 筆文字風、書道感が強い
- **サイズ**: ~1.5MB
- **用途**: タイトル、高級感演出
- **プレビュー**: ぽんしゅルーム / 純米大吟醸
#### Option 3: Shippori Mincho
- **特徴**: 明朝体、洗練された印象
- **サイズ**: ~3MB
- **用途**: フォーマルな表示、詳細画面
- **プレビュー**: ぽんしゅルーム / 純米大吟醸
#### Option 4: Zen Maru Gothic
- **特徴**: ゴシック体、モダン和風
- **サイズ**: ~2MB
- **用途**: 全般的な表示、バランス重視
- **プレビュー**: ぽんしゅルーム / 純米大吟醸
**初回実装: Potta One1種類のみ**
将来的に複数選択肢を追加可能な設計にする。
### 技術仕様
#### A. フォント定義
```dart
enum AppFontStyle {
standard, // システムフォント
pottaOne, // 丸文字(和風カジュアル)
// 将来の拡張:
// yujiSyuku, // 筆文字
// shipporiMincho, // 明朝体
}
```
#### B. テーマ適用
```dart
// app_theme.dart
class AppTheme {
static ThemeData buildTheme({
required Brightness brightness,
required AppFontStyle fontStyle,
}) {
final TextTheme textTheme;
switch (fontStyle) {
case AppFontStyle.pottaOne:
textTheme = GoogleFonts.pottaOneTextTheme();
break;
case AppFontStyle.standard:
default:
textTheme = const TextTheme(); // システムデフォルト
}
return ThemeData(
brightness: brightness,
textTheme: textTheme,
// ... 既存の設定
);
}
}
```
#### C. Provider統合
```dart
class ThemeProvider extends ChangeNotifier {
AppFontStyle _fontStyle = AppFontStyle.standard;
void setFontStyle(AppFontStyle style) {
_fontStyle = style;
notifyListeners();
// Hiveに保存
}
}
```
#### D. UI実装
**設定画面の選択肢:**
```
フォント設定
○ 標準フォント
● 和風フォント(丸文字)
プレビュー:
┌─────────────────┐
│ ぽんしゅルーム │ ← 実際のフォントで表示
│ 純米大吟醸 │
└─────────────────┘
```
### 実装ファイル
| ファイル | 変更内容 |
|---------|---------|
| `pubspec.yaml` | google_fonts: ^6.1.0(既存) |
| `lib/theme/app_theme.dart` | AppFontStyle対応、GoogleFonts統合 |
| `lib/providers/theme_provider.dart` | フォント設定管理 |
| `lib/screens/settings_screen.dart` | フォント選択UI追加 |
| `lib/services/hive_service.dart` | フォント設定の永続化 |
### パフォーマンス考慮
**初回読み込み:**
- Google Fontsは初回のみネットワークからダウンロード
- キャッシュに保存される2回目以降は即座に表示
- ダウンロード中はシステムフォントで表示(フォント切替時の一瞬のちらつき)
**オフライン対応(オプション):**
```yaml
# pubspec.yaml
fonts:
- family: PottaOne
fonts:
- asset: assets/fonts/PottaOne-Regular.ttf
```
- 事前にアセットとして含める(アプリサイズ +2MB
- ネットワーク不要で即座に表示
**推奨: Google Fonts動的読み込み**(初回実装)
アプリサイズを増やさず、将来的に複数フォント追加が容易。
### テスト計画
**1. フォント適用テスト**
- [ ] 設定で「和風フォント」を選択できる
- [ ] 全画面でフォントが変わるHome, Detail, Settings
- [ ] PDFでもフォントが反映される ※重要
- [ ] アプリ再起動後も設定が保持される
**2. 読みやすさテスト**
- [ ] 短文(銘柄名): 視認性OK
- [ ] 長文(説明文): 読みやすさOK
- [ ] 小サイズ10px〜: 潰れない
- [ ] ダークモード: コントラストOK
**3. パフォーマンステスト**
- [ ] 初回読み込み時間: 3秒以内
- [ ] 2回目以降: 即座に表示
- [ ] アプリサイズ増加: 0MB動的読み込み
**4. PDF出力テスト**
- [ ] PDF生成時にPotta Oneが使用される
- [ ] PDFファイルサイズが適切フォント埋め込み
- [ ] 印刷時にフォントが正しく表示される
---
## 実装スケジュール
### Phase 4A: ダークモード自動切替(所要時間: 2-3時間
**Step 1: Provider実装30分**
- [ ] `AppThemeMode` enum追加
- [ ] `effectiveThemeMode` ロジック実装
- [ ] `WidgetsBindingObserver` 統合
**Step 2: UI実装30分**
- [ ] 設定画面に「自動(夜間ダーク)」追加
- [ ] 現在の状態表示を追加
**Step 3: 永続化30分**
- [ ] Hiveに `autoTime` モード保存
- [ ] 起動時の復元処理
**Step 4: テスト1時間**
- [ ] 時刻判定テスト(モック使用)
- [ ] UI動作確認
- [ ] 実機で夜間動作確認
### Phase 4B: 和風フォント対応(所要時間: 2-3時間
**Step 1: テーマ実装30分**
- [ ] `AppFontStyle` enum追加
- [ ] `AppTheme.buildTheme()` にフォント統合
- [ ] GoogleFonts.pottaOne() 適用
**Step 2: Provider実装30分**
- [ ] ThemeProviderにフォント設定追加
- [ ] setFontStyle() 実装
**Step 3: UI実装30分**
- [ ] 設定画面にフォント選択追加
- [ ] プレビュー表示
**Step 4: PDF対応30分**
- [ ] PdfService でフォント設定を参照
- [ ] Potta One をPDFに埋め込み
**Step 5: テスト1時間**
- [ ] 全画面でフォント確認
- [ ] PDF出力確認
- [ ] パフォーマンス計測
---
## リスク管理
### リスク1: Google Fonts読み込み失敗
**シナリオ**: ネットワーク不安定、サーバーダウン
**影響**: フォントがシステムフォントにフォールバック
**対策**:
- エラー時にユーザーに通知
- 次回起動時に再試行
- 最終的にはアセット埋め込みも検討
### リスク2: PDFフォント埋め込み失敗
**シナリオ**: `pdf` パッケージがGoogle Fontsをサポートしない
**影響**: PDFは標準フォントで生成される
**対策**:
- 事前に検証PDF生成テスト
- 必要ならTTFファイルを手動ダウンロードして埋め込み
### リスク3: ダークモード切替のタイミングずれ
**シナリオ**: アプリをバックグラウンドで長時間起動
**影響**: 20:00になってもライトモードのまま
**対策**:
- `WidgetsBindingObserver` で確実に検知
- 設定画面を開いた時も強制再計算
---
## 成果物
### コード変更
- `lib/providers/theme_provider.dart` (+50 lines)
- `lib/theme/app_theme.dart` (+30 lines)
- `lib/screens/settings_screen.dart` (+80 lines)
- `lib/services/hive_service.dart` (+20 lines)
### ドキュメント
- この実装計画書
- ユーザー向けリリースノート(後ほど作成)
### テスト結果レポート
- ダークモード自動切替の動作確認
- フォント適用の全画面スクリーンショット
---
## 次フェーズへの展望
### Phase 4C: フォント拡張(将来)
- 複数フォント選択肢Yuji Syuku, Shippori Mincho
- フォントサイズ調整(大/中/小)
- 部分的フォント適用(タイトルのみ和風、本文は標準)
### Phase 4D: テーマカスタマイズ(将来)
- カラーテーマ選択(青/緑/赤など)
- アクセントカラー変更
- カスタムテーマ保存
---
## 承認
**この計画で実装を開始してよろしいでしょうか?**
承認いただければ、Phase 4Aダークモードから実装を開始します。
---
**End of Plan**