Compare commits
3 Commits
da05455e7c
...
57a2cf89bb
| Author | SHA1 | Date |
|---|---|---|
|
|
57a2cf89bb | |
|
|
c0a23d2afb | |
|
|
9f63578ca7 |
|
|
@ -0,0 +1,66 @@
|
|||
#!/bin/bash
|
||||
# ============================================================================
|
||||
# Ponshu Room Lite - 店舗向けAPKビルドスクリプト
|
||||
# IS_BUSINESS_APP=true / IS_PRO_VERSION=false
|
||||
# ============================================================================
|
||||
|
||||
set -e
|
||||
|
||||
TIMESTAMP=$(date +%Y-%m-%d_%H-%M-%S)
|
||||
OUTPUT_DIR="build/apk_releases/$TIMESTAMP"
|
||||
mkdir -p "$OUTPUT_DIR"
|
||||
|
||||
# APIキー (.env から読み込む)
|
||||
if [ -f "$(dirname "$0")/.env" ]; then
|
||||
export $(grep -v '^#' "$(dirname "$0")/.env" | xargs)
|
||||
fi
|
||||
MAITA_KEY="${MAITA_API_KEY:?MAITA_API_KEY is not set in .env}"
|
||||
EIJI_KEY="${EIJI_API_KEY:?EIJI_API_KEY is not set in .env}"
|
||||
|
||||
# build.gradle.kts バックアップ
|
||||
GRADLE_FILE="android/app/build.gradle.kts"
|
||||
BACKUP_FILE="android/app/build.gradle.kts.backup"
|
||||
cp "$GRADLE_FILE" "$BACKUP_FILE"
|
||||
|
||||
cleanup() {
|
||||
if [ -f "$BACKUP_FILE" ]; then
|
||||
cp "$BACKUP_FILE" "$GRADLE_FILE"
|
||||
rm "$BACKUP_FILE"
|
||||
fi
|
||||
}
|
||||
trap cleanup EXIT
|
||||
|
||||
echo "============================================================================"
|
||||
echo "Ponshu Room Lite - Business APK Build"
|
||||
echo "============================================================================"
|
||||
echo "Output: $OUTPUT_DIR"
|
||||
echo ""
|
||||
|
||||
sed -i 's/applicationId = "com.posimai.ponshu_room"/applicationId = "com.posimai.ponshu_room_lite"/' "$GRADLE_FILE"
|
||||
|
||||
echo "[1/2] Building Maita Business..."
|
||||
flutter build apk --release \
|
||||
--dart-define=GEMINI_API_KEY=$MAITA_KEY \
|
||||
--dart-define=IS_PRO_VERSION=false \
|
||||
--dart-define=IS_BUSINESS_APP=true \
|
||||
--dart-define=USE_PROXY=false
|
||||
|
||||
cp build/app/outputs/flutter-apk/app-release.apk "$OUTPUT_DIR/ponshu_room_business_maita.apk"
|
||||
echo "Saved: $OUTPUT_DIR/ponshu_room_business_maita.apk"
|
||||
echo ""
|
||||
|
||||
echo "[2/2] Building Eiji Business..."
|
||||
flutter build apk --release \
|
||||
--dart-define=GEMINI_API_KEY=$EIJI_KEY \
|
||||
--dart-define=IS_PRO_VERSION=false \
|
||||
--dart-define=IS_BUSINESS_APP=true \
|
||||
--dart-define=USE_PROXY=false
|
||||
|
||||
cp build/app/outputs/flutter-apk/app-release.apk "$OUTPUT_DIR/ponshu_room_business_eiji.apk"
|
||||
echo "Saved: $OUTPUT_DIR/ponshu_room_business_eiji.apk"
|
||||
echo ""
|
||||
|
||||
echo "============================================================================"
|
||||
echo "Business build completed!"
|
||||
echo "============================================================================"
|
||||
ls -lh "$OUTPUT_DIR"
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
#!/bin/bash
|
||||
# ============================================================================
|
||||
# Ponshu Room Lite - 消費者向けAPKビルドスクリプト
|
||||
# IS_BUSINESS_APP=false / IS_PRO_VERSION=false
|
||||
# ============================================================================
|
||||
|
||||
set -e
|
||||
|
||||
TIMESTAMP=$(date +%Y-%m-%d_%H-%M-%S)
|
||||
OUTPUT_DIR="build/apk_releases/$TIMESTAMP"
|
||||
mkdir -p "$OUTPUT_DIR"
|
||||
|
||||
# APIキー (.env から読み込む)
|
||||
if [ -f "$(dirname "$0")/.env" ]; then
|
||||
export $(grep -v '^#' "$(dirname "$0")/.env" | xargs)
|
||||
fi
|
||||
MAITA_KEY="${MAITA_API_KEY:?MAITA_API_KEY is not set in .env}"
|
||||
EIJI_KEY="${EIJI_API_KEY:?EIJI_API_KEY is not set in .env}"
|
||||
|
||||
# build.gradle.kts バックアップ
|
||||
GRADLE_FILE="android/app/build.gradle.kts"
|
||||
BACKUP_FILE="android/app/build.gradle.kts.backup"
|
||||
cp "$GRADLE_FILE" "$BACKUP_FILE"
|
||||
|
||||
cleanup() {
|
||||
if [ -f "$BACKUP_FILE" ]; then
|
||||
cp "$BACKUP_FILE" "$GRADLE_FILE"
|
||||
rm "$BACKUP_FILE"
|
||||
fi
|
||||
}
|
||||
trap cleanup EXIT
|
||||
|
||||
echo "============================================================================"
|
||||
echo "Ponshu Room Lite - Consumer APK Build"
|
||||
echo "============================================================================"
|
||||
echo "Output: $OUTPUT_DIR"
|
||||
echo ""
|
||||
|
||||
sed -i 's/applicationId = "com.posimai.ponshu_room"/applicationId = "com.posimai.ponshu_room_lite"/' "$GRADLE_FILE"
|
||||
|
||||
echo "[1/2] Building Maita Consumer..."
|
||||
flutter build apk --release \
|
||||
--dart-define=GEMINI_API_KEY=$MAITA_KEY \
|
||||
--dart-define=IS_PRO_VERSION=false \
|
||||
--dart-define=IS_BUSINESS_APP=false \
|
||||
--dart-define=USE_PROXY=false
|
||||
|
||||
cp build/app/outputs/flutter-apk/app-release.apk "$OUTPUT_DIR/ponshu_room_consumer_maita.apk"
|
||||
echo "Saved: $OUTPUT_DIR/ponshu_room_consumer_maita.apk"
|
||||
echo ""
|
||||
|
||||
echo "[2/2] Building Eiji Consumer..."
|
||||
flutter build apk --release \
|
||||
--dart-define=GEMINI_API_KEY=$EIJI_KEY \
|
||||
--dart-define=IS_PRO_VERSION=false \
|
||||
--dart-define=IS_BUSINESS_APP=false \
|
||||
--dart-define=USE_PROXY=false
|
||||
|
||||
cp build/app/outputs/flutter-apk/app-release.apk "$OUTPUT_DIR/ponshu_room_consumer_eiji.apk"
|
||||
echo "Saved: $OUTPUT_DIR/ponshu_room_consumer_eiji.apk"
|
||||
echo ""
|
||||
|
||||
echo "============================================================================"
|
||||
echo "Consumer build completed!"
|
||||
echo "============================================================================"
|
||||
ls -lh "$OUTPUT_DIR"
|
||||
|
|
@ -18,20 +18,23 @@ import 'services/migration_service.dart';
|
|||
/// デフォルトはfalse(Lite版) ※ponshu_room_liteディレクトリのため
|
||||
const bool isProVersion = bool.fromEnvironment('IS_PRO_VERSION', defaultValue: false);
|
||||
|
||||
/// 店舗向けビルドかどうかを判定するビルド時フラグ
|
||||
///
|
||||
/// ビルドコマンド:
|
||||
/// - 消費者向け: flutter build apk --release --dart-define=IS_BUSINESS_APP=false
|
||||
/// - 店舗向け: flutter build apk --release --dart-define=IS_BUSINESS_APP=true
|
||||
///
|
||||
/// デフォルトはfalse(消費者向け)
|
||||
const bool isBusinessApp = bool.fromEnvironment('IS_BUSINESS_APP', defaultValue: false);
|
||||
|
||||
void main() async {
|
||||
WidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
// 🔍 DEBUG: Check IS_PRO_VERSION flag
|
||||
debugPrint('🔍 IS_PRO_VERSION = $isProVersion');
|
||||
|
||||
// Initialize Hive
|
||||
await Hive.initFlutter();
|
||||
|
||||
// Register Adapters
|
||||
Hive.registerAdapter(SakeItemAdapter());
|
||||
Hive.registerAdapter(UserProfileAdapter());
|
||||
Hive.registerAdapter(MenuSettingsAdapter());
|
||||
// Phase 0 New Adapters
|
||||
Hive.registerAdapter(DisplayDataAdapter());
|
||||
Hive.registerAdapter(HiddenSpecsAdapter());
|
||||
Hive.registerAdapter(UserDataAdapter());
|
||||
|
|
@ -95,11 +98,8 @@ class MyApp extends ConsumerWidget {
|
|||
GlobalCupertinoLocalizations.delegate,
|
||||
],
|
||||
supportedLocales: const [
|
||||
Locale('ja'), // 日本語
|
||||
Locale('en'), // English
|
||||
// Phase 2: フランス語・ドイツ語を追加予定
|
||||
// Locale('fr'), // Français
|
||||
// Locale('de'), // Deutsch
|
||||
Locale('ja'),
|
||||
Locale('en'),
|
||||
],
|
||||
|
||||
navigatorObservers: [routeObserver],
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|||
import 'package:hive_flutter/hive_flutter.dart';
|
||||
import '../models/sake_item.dart'; // SakeItem exports ItemType
|
||||
import 'filter_providers.dart';
|
||||
import 'theme_provider.dart'; // Phase D6: For isBusinessMode
|
||||
import 'theme_provider.dart';
|
||||
|
||||
// 1. Raw List Stream
|
||||
final rawSakeListItemsProvider = StreamProvider<List<SakeItem>>((ref) {
|
||||
|
|
|
|||
|
|
@ -10,10 +10,10 @@ import 'package:uuid/uuid.dart';
|
|||
import 'package:gal/gal.dart';
|
||||
|
||||
import '../services/gemini_service.dart';
|
||||
import '../services/image_compression_service.dart'; // Phase 4 Added
|
||||
import '../services/image_compression_service.dart';
|
||||
import '../services/gamification_service.dart'; // Badge check
|
||||
import '../services/network_service.dart'; // Phase 1: Offline check
|
||||
import '../services/draft_service.dart'; // Phase 1: Draft save
|
||||
import '../services/network_service.dart';
|
||||
import '../services/draft_service.dart';
|
||||
import '../widgets/analyzing_dialog.dart';
|
||||
import '../models/sake_item.dart';
|
||||
import '../theme/app_colors.dart';
|
||||
|
|
@ -42,13 +42,11 @@ class _CameraScreenState extends ConsumerState<CameraScreen> with SingleTickerPr
|
|||
bool _isTakingPicture = false;
|
||||
DateTime? _quotaLockoutTime;
|
||||
|
||||
// Phase 3-B: Focus & Zoom
|
||||
double _minZoom = 1.0;
|
||||
double _maxZoom = 1.0;
|
||||
double _currentZoom = 1.0;
|
||||
double _baseScale = 1.0; // For pinch reference
|
||||
double _baseScale = 1.0;
|
||||
|
||||
// Phase 3-B2: Exposure
|
||||
double _minExposure = 0.0;
|
||||
double _maxExposure = 0.0;
|
||||
double _currentExposureOffset = 0.0;
|
||||
|
|
@ -77,14 +75,10 @@ class _CameraScreenState extends ConsumerState<CameraScreen> with SingleTickerPr
|
|||
|
||||
_initializeControllerFuture = _controller!.initialize().then((_) async {
|
||||
if (!mounted) return;
|
||||
// [Phase 3-B] Get Zoom Range
|
||||
_minZoom = await _controller!.getMinZoomLevel();
|
||||
_maxZoom = await _controller!.getMaxZoomLevel();
|
||||
// [Phase 3-B2] Get Exposure Range
|
||||
_minExposure = await _controller!.getMinExposureOffset();
|
||||
_maxExposure = await _controller!.getMaxExposureOffset();
|
||||
|
||||
// [Phase 3-B] Set Auto Focus Mode
|
||||
await _controller!.setFocusMode(FocusMode.auto);
|
||||
setState(() {});
|
||||
});
|
||||
|
|
@ -205,9 +199,7 @@ class _CameraScreenState extends ConsumerState<CameraScreen> with SingleTickerPr
|
|||
await _initializeControllerFuture;
|
||||
final image = await _controller!.takePicture();
|
||||
|
||||
// Save image locally (App Sandbox)
|
||||
final directory = await getApplicationDocumentsDirectory();
|
||||
// Phase 4 Improvement: Apply Compression (Target Max 1MB)
|
||||
// 1. Save temp raw file
|
||||
final tempPath = join(directory.path, '${const Uuid().v4()}_temp.jpg');
|
||||
await image.saveTo(tempPath);
|
||||
|
|
@ -270,7 +262,6 @@ class _CameraScreenState extends ConsumerState<CameraScreen> with SingleTickerPr
|
|||
if (images.isNotEmpty && mounted) {
|
||||
// IF RETURN PATH Mode (Only supports one)
|
||||
if (widget.mode == CameraMode.returnPath) {
|
||||
// Phase D3: Compress and persist gallery image
|
||||
final directory = await getApplicationDocumentsDirectory();
|
||||
final finalPath = join(directory.path, '${const Uuid().v4()}.jpg');
|
||||
final compressedPath = await ImageCompressionService.compressForGemini(
|
||||
|
|
@ -283,7 +274,6 @@ class _CameraScreenState extends ConsumerState<CameraScreen> with SingleTickerPr
|
|||
return;
|
||||
}
|
||||
|
||||
// Phase D3: Compress and persist all gallery images to Documents directory
|
||||
final directory = await getApplicationDocumentsDirectory();
|
||||
|
||||
for (var img in images) {
|
||||
|
|
@ -381,7 +371,6 @@ class _CameraScreenState extends ConsumerState<CameraScreen> with SingleTickerPr
|
|||
Future<void> _analyzeImages() async {
|
||||
if (_capturedImages.isEmpty) return;
|
||||
|
||||
// Phase 1: オフライン検知 - Draft保存処理
|
||||
final isOnline = await NetworkService.isOnline();
|
||||
if (!isOnline) {
|
||||
// オフライン時: Draft として保存
|
||||
|
|
@ -950,9 +939,10 @@ class _ExposureSliderPainter extends CustomPainter {
|
|||
// minValue (e.g., -4.0) -> 0.0 (bottom)
|
||||
// 0.0 (center) -> 0.5 (middle)
|
||||
// maxValue (e.g., +4.0) -> 1.0 (top)
|
||||
final normalized = (currentValue - minValue) / range; // Debug
|
||||
debugPrint('CustomPainter: value=$currentValue, min=$minValue, max=$maxValue, range=$range, normalized=${normalized.toStringAsFixed(3)}'); // Map to Y coordinate: 0.0 (normalized) -> bottom, 1.0 (normalized) -> top
|
||||
final knobY = (size.height - 20) * (1.0 - normalized) + 10; debugPrint(' -> knobY=${knobY.toStringAsFixed(1)} (height=${size.height})'); // Draw knob shadow
|
||||
final normalized = (currentValue - minValue) / range;
|
||||
// Map to Y coordinate: 0.0 (normalized) -> bottom, 1.0 (normalized) -> top
|
||||
final knobY = (size.height - 20) * (1.0 - normalized) + 10;
|
||||
// Draw knob shadow
|
||||
canvas.drawCircle(Offset(trackX, knobY), 7, knobShadowPaint);
|
||||
// Draw knob
|
||||
canvas.drawCircle(Offset(trackX, knobY), 6, knobPaint);
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import '../../widgets/map/prefecture_tile_map.dart';
|
|||
import '../../theme/app_colors.dart';
|
||||
import '../../models/maps/japan_map_data.dart';
|
||||
import '../../providers/ui_experiment_provider.dart';
|
||||
import '../../models/schema/item_type.dart'; // Phase D4: For ItemType.sake filtering
|
||||
import '../../models/schema/item_type.dart';
|
||||
import '../../widgets/common/error_retry_widget.dart';
|
||||
|
||||
class BreweryMapScreen extends ConsumerStatefulWidget {
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import 'package:share_plus/share_plus.dart';
|
|||
import 'package:path_provider/path_provider.dart';
|
||||
import '../../providers/sake_list_provider.dart';
|
||||
import '../../services/shuko_diagnosis_service.dart';
|
||||
import '../../providers/theme_provider.dart'; // v1.1 Fix
|
||||
import '../../providers/theme_provider.dart';
|
||||
import '../../theme/app_colors.dart';
|
||||
import '../../widgets/sake_radar_chart.dart';
|
||||
import '../../widgets/contextual_help_icon.dart';
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import 'menu_creation_screen.dart';
|
|||
import '../theme/app_colors.dart';
|
||||
import '../providers/sake_list_provider.dart';
|
||||
import '../providers/filter_providers.dart';
|
||||
import '../providers/menu_providers.dart'; // Phase 2-1
|
||||
import '../providers/menu_providers.dart';
|
||||
import '../models/sake_item.dart';
|
||||
import '../widgets/sake_search_delegate.dart';
|
||||
import '../widgets/onboarding_dialog.dart';
|
||||
|
|
@ -22,7 +22,7 @@ import '../providers/ui_experiment_provider.dart'; // A/B Test
|
|||
import 'package:flutter_speed_dial/flutter_speed_dial.dart';
|
||||
import 'package:lucide_icons/lucide_icons.dart';
|
||||
import '../widgets/prefecture_filter_sheet.dart';
|
||||
import '../widgets/pending_analysis_banner.dart'; // Phase 1: Banner widget
|
||||
import '../widgets/pending_analysis_banner.dart';
|
||||
import '../widgets/common/error_retry_widget.dart';
|
||||
|
||||
// CR-006: NotifierProviderでオンボーディングチェック状態を管理(グローバル変数を削除)
|
||||
|
|
|
|||
|
|
@ -127,12 +127,10 @@ class _MainScreenState extends ConsumerState<MainScreen> {
|
|||
});
|
||||
|
||||
final userProfile = ref.watch(userProfileProvider);
|
||||
final isBusiness = userProfile.isBusinessMode;
|
||||
// isBusinessApp=false(消費者向けビルド)では店舗モードを完全に無効化
|
||||
final isBusiness = isBusinessApp && userProfile.isBusinessMode;
|
||||
final t = Translations(userProfile.locale); // Translation helper
|
||||
|
||||
// 🔍 DEBUG: Check IS_PRO_VERSION flag
|
||||
debugPrint('🔍 MainScreen: IS_PRO_VERSION = $isProVersion, isBusiness = $isBusiness');
|
||||
|
||||
// Define Screens for each mode
|
||||
// Lite版のPro限定タブは表示されないようにダミー画面を配置
|
||||
// (タップ時にダイアログで対応するため、画面遷移は発生しない)
|
||||
|
|
|
|||
|
|
@ -14,8 +14,6 @@ import '../widgets/gamification/activity_stats.dart';
|
|||
import '../theme/app_colors.dart';
|
||||
import '../services/mbti_types.dart'; // Needed for type title display
|
||||
|
||||
// v1.5
|
||||
|
||||
class SoulScreen extends ConsumerStatefulWidget {
|
||||
const SoulScreen({super.key});
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import 'package:flutter/material.dart';
|
|||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:lucide_icons/lucide_icons.dart';
|
||||
import '../../providers/sake_list_provider.dart';
|
||||
import '../../models/schema/item_type.dart'; // Phase D5: For filtering set products
|
||||
import '../../models/schema/item_type.dart';
|
||||
|
||||
|
||||
class ActivityStats extends ConsumerWidget {
|
||||
|
|
|
|||
|
|
@ -26,9 +26,6 @@ class LanguageSelector extends ConsumerWidget {
|
|||
final languages = [
|
||||
{'code': 'ja', 'name': '日本語', 'flag': '🇯🇵'},
|
||||
{'code': 'en', 'name': 'English', 'flag': '🇺🇸'},
|
||||
// Phase 2: フランス語・ドイツ語を追加予定
|
||||
// {'code': 'fr', 'name': 'Français', 'flag': '🇫🇷'},
|
||||
// {'code': 'de', 'name': 'Deutsch', 'flag': '🇩🇪'},
|
||||
];
|
||||
|
||||
showDialog(
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
|
|||
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
||||
# In Windows, build-name is used as the major, minor, and patch parts
|
||||
# of the product and file versions while build-number is used as the build suffix.
|
||||
version: 1.0.16+27
|
||||
version: 1.0.17+28
|
||||
|
||||
environment:
|
||||
sdk: ^3.10.1
|
||||
|
|
|
|||
|
|
@ -0,0 +1,21 @@
|
|||
{
|
||||
"date": "2026-04-04",
|
||||
"name": "Ponshu Room 1.0.17 (2026-04-04)",
|
||||
"version": "v1.0.17",
|
||||
"apks": {
|
||||
"eiji": {
|
||||
"lite": {
|
||||
"url": "https://posimai-lab.tail72e846.ts.net/mai/ponshu-room-lite/releases/download/v1.0.17/ponshu_room_consumer_eiji.apk",
|
||||
"size_mb": 89,
|
||||
"filename": "ponshu_room_consumer_eiji.apk"
|
||||
}
|
||||
},
|
||||
"maita": {
|
||||
"lite": {
|
||||
"url": "https://posimai-lab.tail72e846.ts.net/mai/ponshu-room-lite/releases/download/v1.0.17/ponshu_room_consumer_maita.apk",
|
||||
"size_mb": 89,
|
||||
"filename": "ponshu_room_consumer_maita.apk"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue