Code Cleanup: Fix analyzer issues (unused vars, dead code, logic, pdf_service restoration)

This commit is contained in:
Ponshu Developer 2026-01-13 10:33:13 +09:00
parent 191e334d0d
commit e038fff77f
6 changed files with 70 additions and 66 deletions

View File

@ -17,7 +17,8 @@
"Read(//c/Users/maita/posimai-project/ponshu-room/**)", "Read(//c/Users/maita/posimai-project/ponshu-room/**)",
"Bash(flutter build:*)", "Bash(flutter build:*)",
"Bash(unzip:*)", "Bash(unzip:*)",
"Bash(ls:*)" "Bash(ls:*)",
"Bash(awk:*)"
], ],
"deny": [], "deny": [],
"ask": [] "ask": []

View File

@ -46,7 +46,7 @@ class HomeScreen extends ConsumerWidget {
if (!_hasCheckedOnboarding) { if (!_hasCheckedOnboarding) {
Future.microtask(() { Future.microtask(() {
final profile = ref.read(userProfileProvider); final profile = ref.read(userProfileProvider);
if (!profile.hasCompletedOnboarding) { if (!profile.hasCompletedOnboarding && context.mounted) {
_showOnboardingDialog(context, ref); _showOnboardingDialog(context, ref);
} }
_hasCheckedOnboarding = true; _hasCheckedOnboarding = true;
@ -56,7 +56,6 @@ class HomeScreen extends ConsumerWidget {
// Filter States // Filter States
final isSearching = ref.watch(sakeSearchQueryProvider).isNotEmpty; final isSearching = ref.watch(sakeSearchQueryProvider).isNotEmpty;
final showFavorites = ref.watch(sakeFilterFavoriteProvider); final showFavorites = ref.watch(sakeFilterFavoriteProvider);
final selectedTag = ref.watch(sakeFilterTagProvider);
final selectedPrefecture = ref.watch(sakeFilterPrefectureProvider); final selectedPrefecture = ref.watch(sakeFilterPrefectureProvider);
final isMenuMode = ref.watch(menuModeProvider); final isMenuMode = ref.watch(menuModeProvider);
@ -92,9 +91,7 @@ class HomeScreen extends ConsumerWidget {
) )
: null), : null),
actions: [ actions: [
if (false) ...[
// Menu Mode Actions
] else ...[
// Normal Actions // Normal Actions
if (isBusinessMode) if (isBusinessMode)
IconButton( IconButton(
@ -141,7 +138,7 @@ class HomeScreen extends ConsumerWidget {
onPressed: () => _showUsageGuide(context, ref), onPressed: () => _showUsageGuide(context, ref),
tooltip: 'ヘルプ・ガイド', tooltip: 'ヘルプ・ガイド',
), ),
],
], ],
), ),
body: SafeArea( body: SafeArea(

View File

@ -368,29 +368,6 @@ class PdfService {
// Helper for multi-price display (used in new layout)
static pw.Widget _buildMultiPriceTag(Map<String, int> 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) { static pw.Widget _buildCompactPriceTag(SakeItem item, int calcPrice, double fontSize, pw.Font font) {
if (item.userData.priceVariants != null && item.userData.priceVariants!.isNotEmpty) { if (item.userData.priceVariants != null && item.userData.priceVariants!.isNotEmpty) {
@ -417,19 +394,6 @@ class PdfService {
return pw.SizedBox(); 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) { static PdfPageFormat _getPageFormat(String size) {
switch (size) { switch (size) {
case 'a5': return PdfPageFormat.a5; // 148 x 210 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 _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 _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 _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) { static double _getImageSize(String pdfSize) {
switch (pdfSize) { switch (pdfSize) {
@ -459,13 +422,7 @@ class PdfService {
static double _getPageMargin(String pdfSize) => 10.0 * PdfPageFormat.mm; static double _getPageMargin(String pdfSize) => 10.0 * PdfPageFormat.mm;
static double _getGridSpacing(String pdfSize) => 8.0; 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) { static int _getCrossAxisCount(String pdfSize) {
switch (pdfSize) { switch (pdfSize) {
@ -474,7 +431,4 @@ class PdfService {
case 'a4': default: return 2; case 'a4': default: return 2;
} }
} }
// Unused but kept if needed for reference
static double _getChildAspectRatio(String pdfSize) => 1.0;
} }

View File

@ -69,7 +69,7 @@ class PrefectureTileMap extends StatelessWidget {
alignment: Alignment.center, alignment: Alignment.center,
decoration: BoxDecoration( decoration: BoxDecoration(
borderRadius: BorderRadius.circular(6), 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( child: Text(
prefName, prefName,

View File

@ -3,11 +3,11 @@ import 'dart:convert';
import 'package:ponshu_room_lite/secrets.dart'; import 'package:ponshu_room_lite/secrets.dart';
void main() async { void main() async {
print('Checking available Gemini models via API...'); stdout.writeln('Checking available Gemini models via API...');
final apiKey = Secrets.geminiApiKey; final apiKey = Secrets.geminiApiKey;
if (apiKey.isEmpty) { if (apiKey.isEmpty) {
print('API Key is empty in Secrets.'); stdout.writeln('API Key is empty in Secrets.');
return; return;
} }
@ -23,28 +23,28 @@ void main() async {
final responseBody = await response.transform(utf8.decoder).join(); final responseBody = await response.transform(utf8.decoder).join();
final json = jsonDecode(responseBody); final json = jsonDecode(responseBody);
print('\n--- Available Models ---'); stdout.writeln('\n--- Available Models ---');
if (json['models'] != null) { if (json['models'] != null) {
for (var model in json['models']) { for (var model in json['models']) {
// Filter for "generateContent" supported models // Filter for "generateContent" supported models
final supportedMethods = model['supportedGenerationMethods'] as List?; final supportedMethods = model['supportedGenerationMethods'] as List?;
if (supportedMethods != null && supportedMethods.contains('generateContent')) { if (supportedMethods != null && supportedMethods.contains('generateContent')) {
print('Name: ${model['name']}'); stdout.writeln('Name: ${model['name']}');
print('Display Name: ${model['displayName']}'); stdout.writeln('Display Name: ${model['displayName']}');
print('Description: ${model['description']}'); stdout.writeln('Description: ${model['description']}');
print('-------------------------'); stdout.writeln('-------------------------');
} }
} }
} else { } else {
print('No models found in response.'); stdout.writeln('No models found in response.');
} }
} else { } 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(); final responseBody = await response.transform(utf8.decoder).join();
print('Response: $responseBody'); stdout.writeln('Response: $responseBody');
} }
httpClient.close(); httpClient.close();
} catch (e) { } catch (e) {
print('Error checking models: $e'); stdout.writeln('Error checking models: $e');
} }
} }

52
walkthrough.md Normal file
View File

@ -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 リリース
以下の新機能を含む安定版です。
- 🗺️ **酒蔵マップ**: 都道府県別タイルマップの実装により、制覇状況が視覚的にわかりやすくなりました。
- 🍷 **ソムリエ診断**: ユーザー名と性別を考慮したパーソナライズ診断機能を追加。
- 🔧 **安定性**: 多くのバグ修正とパフォーマンス改善。