From e038fff77fdabaaff2112572ec89df754ed6cb6c Mon Sep 17 00:00:00 2001 From: Ponshu Developer Date: Tue, 13 Jan 2026 10:33:13 +0900 Subject: [PATCH] Code Cleanup: Fix analyzer issues (unused vars, dead code, logic, pdf_service restoration) --- .claude/settings.local.json | 3 +- lib/screens/home_screen.dart | 9 ++-- lib/services/pdf_service.dart | 48 +--------------------- lib/widgets/map/prefecture_tile_map.dart | 2 +- tool/check_models.dart | 22 +++++----- walkthrough.md | 52 ++++++++++++++++++++++++ 6 files changed, 70 insertions(+), 66 deletions(-) create mode 100644 walkthrough.md diff --git a/.claude/settings.local.json b/.claude/settings.local.json index 34b8e46..fe8f899 100644 --- a/.claude/settings.local.json +++ b/.claude/settings.local.json @@ -17,7 +17,8 @@ "Read(//c/Users/maita/posimai-project/ponshu-room/**)", "Bash(flutter build:*)", "Bash(unzip:*)", - "Bash(ls:*)" + "Bash(ls:*)", + "Bash(awk:*)" ], "deny": [], "ask": [] diff --git a/lib/screens/home_screen.dart b/lib/screens/home_screen.dart index 2d32ca6..bfee7bd 100644 --- a/lib/screens/home_screen.dart +++ b/lib/screens/home_screen.dart @@ -46,7 +46,7 @@ class HomeScreen extends ConsumerWidget { if (!_hasCheckedOnboarding) { Future.microtask(() { final profile = ref.read(userProfileProvider); - if (!profile.hasCompletedOnboarding) { + if (!profile.hasCompletedOnboarding && context.mounted) { _showOnboardingDialog(context, ref); } _hasCheckedOnboarding = true; @@ -56,7 +56,6 @@ class HomeScreen extends ConsumerWidget { // Filter States final isSearching = ref.watch(sakeSearchQueryProvider).isNotEmpty; final showFavorites = ref.watch(sakeFilterFavoriteProvider); - final selectedTag = ref.watch(sakeFilterTagProvider); final selectedPrefecture = ref.watch(sakeFilterPrefectureProvider); final isMenuMode = ref.watch(menuModeProvider); @@ -92,9 +91,7 @@ class HomeScreen extends ConsumerWidget { ) : null), actions: [ - if (false) ...[ - // Menu Mode Actions - ] else ...[ + // Normal Actions if (isBusinessMode) IconButton( @@ -141,7 +138,7 @@ class HomeScreen extends ConsumerWidget { onPressed: () => _showUsageGuide(context, ref), tooltip: 'ヘルプ・ガイド', ), - ], + ], ), body: SafeArea( diff --git a/lib/services/pdf_service.dart b/lib/services/pdf_service.dart index 3ccac53..97630a2 100644 --- a/lib/services/pdf_service.dart +++ b/lib/services/pdf_service.dart @@ -368,29 +368,6 @@ class PdfService { - // Helper for multi-price display (used in new layout) - static pw.Widget _buildMultiPriceTag(Map priceVariants, double fontSize, pw.Font font) { - return pw.Wrap( - spacing: 8, - runSpacing: 2, - children: priceVariants.entries.take(3).map((e) => - pw.RichText( - text: pw.TextSpan( - children: [ - pw.TextSpan( - text: '${e.key} ', - style: pw.TextStyle(font: font, fontSize: fontSize * 0.75, color: PdfColors.grey700), - ), - pw.TextSpan( - text: '${PricingHelper.formatPrice(e.value)}円', - style: pw.TextStyle(font: font, fontSize: fontSize, fontWeight: pw.FontWeight.bold), - ), - ], - ), - ), - ).toList(), - ); - } static pw.Widget _buildCompactPriceTag(SakeItem item, int calcPrice, double fontSize, pw.Font font) { if (item.userData.priceVariants != null && item.userData.priceVariants!.isNotEmpty) { @@ -417,19 +394,6 @@ class PdfService { return pw.SizedBox(); } - static pw.Widget _buildStarRating(String label, int value, pw.Font font, String pdfSize) { - final double starFontSize = _getStarFontSize(pdfSize); - return pw.Row( - crossAxisAlignment: pw.CrossAxisAlignment.center, - children: [ - pw.Text(label, style: pw.TextStyle(fontSize: starFontSize, font: font, color: PdfColors.grey600)), - pw.SizedBox(width: 2), - pw.Text('★' * value + '☆' * (5 - value), style: pw.TextStyle(fontSize: starFontSize, font: font, color: PdfColors.orange400)), - ] - ); - } - - static PdfPageFormat _getPageFormat(String size) { switch (size) { case 'a5': return PdfPageFormat.a5; // 148 x 210 @@ -445,7 +409,6 @@ class PdfService { static double _getPriceFontSize(String pdfSize) => pdfSize == 'a5' ? 12.0 : (pdfSize == 'b5' ? 12.0 : 14.0); static double _getInfoFontSize(String pdfSize) => pdfSize == 'a5' ? 8.0 : (pdfSize == 'b5' ? 8.0 : 9.0); static double _getPoemFontSize(String pdfSize) => pdfSize == 'a5' ? 8.5 : (pdfSize == 'b5' ? 8.5 : 10.0); - static double _getStarFontSize(String pdfSize) => pdfSize == 'a5' ? 6.0 : 7.0; static double _getImageSize(String pdfSize) { switch (pdfSize) { @@ -459,13 +422,7 @@ class PdfService { static double _getPageMargin(String pdfSize) => 10.0 * PdfPageFormat.mm; static double _getGridSpacing(String pdfSize) => 8.0; - static int _getItemsPerPage(String pdfSize) { - switch (pdfSize) { - case 'a5': return 5; // Portrait, 1 col, 5 items - case 'b5': return 8; - case 'a4': default: return 10; - } - } + static int _getCrossAxisCount(String pdfSize) { switch (pdfSize) { @@ -474,7 +431,4 @@ class PdfService { case 'a4': default: return 2; } } - - // Unused but kept if needed for reference - static double _getChildAspectRatio(String pdfSize) => 1.0; } diff --git a/lib/widgets/map/prefecture_tile_map.dart b/lib/widgets/map/prefecture_tile_map.dart index 2dc04fc..e0eed6d 100644 --- a/lib/widgets/map/prefecture_tile_map.dart +++ b/lib/widgets/map/prefecture_tile_map.dart @@ -69,7 +69,7 @@ class PrefectureTileMap extends StatelessWidget { alignment: Alignment.center, decoration: BoxDecoration( borderRadius: BorderRadius.circular(6), - border: Border.all(color: Colors.white.withValues(alpha: 0.2), width: 1), // Subtle inner border + border: Border.all(color: borderColor, width: 1), // Subtle inner border ), child: Text( prefName, diff --git a/tool/check_models.dart b/tool/check_models.dart index b68cc61..012000a 100644 --- a/tool/check_models.dart +++ b/tool/check_models.dart @@ -3,11 +3,11 @@ import 'dart:convert'; import 'package:ponshu_room_lite/secrets.dart'; void main() async { - print('Checking available Gemini models via API...'); + stdout.writeln('Checking available Gemini models via API...'); final apiKey = Secrets.geminiApiKey; if (apiKey.isEmpty) { - print('API Key is empty in Secrets.'); + stdout.writeln('API Key is empty in Secrets.'); return; } @@ -23,28 +23,28 @@ void main() async { final responseBody = await response.transform(utf8.decoder).join(); final json = jsonDecode(responseBody); - print('\n--- Available Models ---'); + stdout.writeln('\n--- Available Models ---'); if (json['models'] != null) { for (var model in json['models']) { // Filter for "generateContent" supported models final supportedMethods = model['supportedGenerationMethods'] as List?; if (supportedMethods != null && supportedMethods.contains('generateContent')) { - print('Name: ${model['name']}'); - print('Display Name: ${model['displayName']}'); - print('Description: ${model['description']}'); - print('-------------------------'); + stdout.writeln('Name: ${model['name']}'); + stdout.writeln('Display Name: ${model['displayName']}'); + stdout.writeln('Description: ${model['description']}'); + stdout.writeln('-------------------------'); } } } else { - print('No models found in response.'); + stdout.writeln('No models found in response.'); } } else { - print('Failed to list models. Status Code: ${response.statusCode}'); + stdout.writeln('Failed to list models. Status Code: ${response.statusCode}'); final responseBody = await response.transform(utf8.decoder).join(); - print('Response: $responseBody'); + stdout.writeln('Response: $responseBody'); } httpClient.close(); } catch (e) { - print('Error checking models: $e'); + stdout.writeln('Error checking models: $e'); } } diff --git a/walkthrough.md b/walkthrough.md new file mode 100644 index 0000000..0bcf4fe --- /dev/null +++ b/walkthrough.md @@ -0,0 +1,52 @@ +# Phase 0: Emergency Fixes & Enhancements + +ユーザーフィードバックに基づく優先度の高い改善と、コードベースのクリーンアップを実施しました。 + +## 1. ビジネスモードの強化 (Task 0-1) +ビジネスモード(飲食店向け)の作業効率を向上させるため、ホーム画面のFAB( + ボタン)を刷新しました。 +- **実装**: `SpeedDial` (展開式メニュー) を採用。 +- **機能**: + - 📸 **商品を撮影**: カメラを起動して在庫登録。 + - 🖼️ **画像の読み込み**: ギャラリーからインポート。 + - 📦 **セット商品を追加**: 飲み比べセットなどの手動登録を作成。 + - 🍶 **お品書き作成**: メニュー作成画面へショートカット。 + +## 2. カメラ UI の刷新 (Task 0-2) +撮影体験を向上させるため、カメラ画面の操作系を大幅に改善しました。 +- **露出補正 (明るさ)**: インスタグラム風の垂直スライダーを採用。操作のレスポンスを改善し、滑らかな調整が可能に。 +- **ズーム制御**: 従来のピンチ操作に加え、「1.0」「2.0」「3.0」のワンタップ切り替えボタンを追加。 +- **ピンチ操作**: 感度を調整し、意図しない急激なズームを防ぐよう最適化。 + +## 3. コードクリーンアップ (Task 0-3) +長期的な保守性を高めるため、UIコンポーネントの統一を行いました。 +- **アイコン統一**: `Icons.*` (Material) と混在していたアイコンを、洗練された `Lucide Icons` に統一。 + - 全画面(ホーム、詳細、設定、カメラなど)で適用済み。 +- **パディング統一**: `AppTheme` に定数 (`spacingSmall: 8`, `spacingMedium: 16` 等) を定義し、リストやグリッドの余白を標準化。 +- **安全性確認**: `SakeItem.copyWith` のパラメータ漏れがないことを検証済み。 + +## 4. リリース準備 +- **ビルド**: `flutter build apk --release` によるリリースビルドの生成を確認済み。 +- **バージョン**: `v1.0.8+16` (または最新) + +次のフェーズ(ビジネスモード機能拡張)に向けた基盤が整いました。 + +# Phase 19: Code Cleanup & v1.2 Release + + APKサイズ最適化とコードの健全性を確保し、v1.2としてリリースしました。 + +## 1. APKサイズ最適化 (111.1MB) +リリースビルドのサイズを 17MB 削減しました(128MB → 111.1MB)。 +- **ABIフィルタリング**: `arm64-v8a` に限定し、不要なアーキテクチャのバイナリを除外。 +- **依存関係の整理**: 未使用だった `rive` パッケージを削除。 + +## 2. コードクリーンアップ +長期的なメンテナンス性を確保するため、技術的負債を解消しました。 +- **静的解析**: `flutter analyze` で検出された デッドコード、未使用変数、`print` 文を修正。 +- **ロジック修正**: ソートロジックなどの潜在的なバグを解消。 + +## 3. v1.2 リリース +以下の新機能を含む安定版です。 +- 🗺️ **酒蔵マップ**: 都道府県別タイルマップの実装により、制覇状況が視覚的にわかりやすくなりました。 +- 🍷 **ソムリエ診断**: ユーザー名と性別を考慮したパーソナライズ診断機能を追加。 +- 🔧 **安定性**: 多くのバグ修正とパフォーマンス改善。 +