refactor(ui): 화면 UI 정리

- front_screen: 프론트 화면 레이아웃 개선
- settings_screen: 설정 화면 간소화
- new_character_screen: 캐릭터 생성 화면 정리
This commit is contained in:
JiWoong Sul
2026-01-19 19:41:01 +09:00
parent 71740abe8f
commit d5c46ad04a
3 changed files with 41 additions and 47 deletions

View File

@@ -321,8 +321,8 @@ class _ActionButtons extends StatelessWidget {
onPressed: onSettings, onPressed: onSettings,
isPrimary: false, isPrimary: false,
), ),
// IAP 구매 (광고 제거) - 스토어 사용 가능하고 미구매 상태일 때만 표시 // IAP 구매 (광고 제거) - 스토어 사용 가능할 때 표시 (구매 완료 시 비활성화)
if (removeAdsPrice != null && !isAdRemovalPurchased) ...[ if (removeAdsPrice != null) ...[
const SizedBox(height: 20), const SizedBox(height: 20),
const Divider(color: RetroColors.panelBorderInner, height: 1), const Divider(color: RetroColors.panelBorderInner, height: 1),
const SizedBox(height: 12), const SizedBox(height: 12),
@@ -330,13 +330,12 @@ class _ActionButtons extends StatelessWidget {
price: removeAdsPrice!, price: removeAdsPrice!,
onPurchase: onPurchaseRemoveAds, onPurchase: onPurchaseRemoveAds,
onRestore: onRestorePurchase, onRestore: onRestorePurchase,
enabled: !isAdRemovalPurchased,
), ),
], ],
// 이미 구매된 경우 표시 // 이미 구매된 경우 배지 표시
if (isAdRemovalPurchased) ...[ if (isAdRemovalPurchased) ...[
const SizedBox(height: 20), const SizedBox(height: 8),
const Divider(color: RetroColors.panelBorderInner, height: 1),
const SizedBox(height: 12),
_PurchasedBadge(), _PurchasedBadge(),
], ],
], ],
@@ -412,11 +411,13 @@ class _IapPurchaseButton extends StatelessWidget {
required this.price, required this.price,
this.onPurchase, this.onPurchase,
this.onRestore, this.onRestore,
this.enabled = true,
}); });
final String price; final String price;
final VoidCallback? onPurchase; final VoidCallback? onPurchase;
final VoidCallback? onRestore; final VoidCallback? onRestore;
final bool enabled;
void _showPurchaseDialog(BuildContext context) { void _showPurchaseDialog(BuildContext context) {
showDialog<void>( showDialog<void>(
@@ -433,23 +434,33 @@ class _IapPurchaseButton extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
// 비활성화 상태의 색상
final buttonColor = enabled ? RetroColors.gold : RetroColors.textDisabled;
final bgGradient = enabled
? const LinearGradient(
colors: [Color(0xFF4A3B2A), Color(0xFF3D2E1F)],
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
)
: const LinearGradient(
colors: [Color(0xFF3A3A3A), Color(0xFF2A2A2A)],
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
);
return Column( return Column(
crossAxisAlignment: CrossAxisAlignment.stretch, crossAxisAlignment: CrossAxisAlignment.stretch,
children: [ children: [
// 구매 버튼 (클릭 시 팝업) // 구매 버튼 (클릭 시 팝업)
Container( Container(
decoration: BoxDecoration( decoration: BoxDecoration(
gradient: const LinearGradient( gradient: bgGradient,
colors: [Color(0xFF4A3B2A), Color(0xFF3D2E1F)], border: Border.all(color: buttonColor, width: 2),
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
),
border: Border.all(color: RetroColors.gold, width: 2),
), ),
child: Material( child: Material(
color: Colors.transparent, color: Colors.transparent,
child: InkWell( child: InkWell(
onTap: () => _showPurchaseDialog(context), onTap: enabled ? () => _showPurchaseDialog(context) : null,
child: Padding( child: Padding(
padding: const EdgeInsets.symmetric( padding: const EdgeInsets.symmetric(
horizontal: 16, horizontal: 16,
@@ -457,7 +468,7 @@ class _IapPurchaseButton extends StatelessWidget {
), ),
child: Row( child: Row(
children: [ children: [
const Icon(Icons.block, color: RetroColors.gold, size: 24), Icon(Icons.block, color: buttonColor, size: 24),
const SizedBox(width: 12), const SizedBox(width: 12),
Expanded( Expanded(
child: Column( child: Column(
@@ -465,10 +476,10 @@ class _IapPurchaseButton extends StatelessWidget {
children: [ children: [
Text( Text(
game_l10n.iapRemoveAds, game_l10n.iapRemoveAds,
style: const TextStyle( style: TextStyle(
fontFamily: 'PressStart2P', fontFamily: 'PressStart2P',
fontSize: 12, fontSize: 12,
color: RetroColors.gold, color: buttonColor,
), ),
), ),
const SizedBox(height: 4), const SizedBox(height: 4),
@@ -484,11 +495,7 @@ class _IapPurchaseButton extends StatelessWidget {
), ),
), ),
// 화살표 아이콘 (상세 보기) // 화살표 아이콘 (상세 보기)
const Icon( Icon(Icons.arrow_forward_ios, color: buttonColor, size: 16),
Icons.arrow_forward_ios,
color: RetroColors.gold,
size: 16,
),
], ],
), ),
), ),
@@ -499,7 +506,7 @@ class _IapPurchaseButton extends StatelessWidget {
// 복원 버튼 // 복원 버튼
Center( Center(
child: TextButton( child: TextButton(
onPressed: onRestore, onPressed: enabled ? onRestore : null,
child: Text( child: Text(
game_l10n.iapRestorePurchase, game_l10n.iapRestorePurchase,
style: const TextStyle( style: const TextStyle(
@@ -569,7 +576,10 @@ class _IapPurchaseDialog extends StatelessWidget {
const SizedBox(height: 8), const SizedBox(height: 8),
_BenefitItem(icon: Icons.speed, text: game_l10n.iapBenefit5), _BenefitItem(icon: Icons.speed, text: game_l10n.iapBenefit5),
const SizedBox(height: 8), const SizedBox(height: 8),
_BenefitItem(icon: Icons.inventory_2, text: game_l10n.iapBenefit6), _BenefitItem(
icon: Icons.inventory_2,
text: game_l10n.iapBenefit6,
),
const SizedBox(height: 20), const SizedBox(height: 20),
// 가격 + 구매 버튼 // 가격 + 구매 버튼
Container( Container(

View File

@@ -803,7 +803,6 @@ class _NewCharacterScreenState extends State<NewCharacterScreen> {
PassiveType.magicDamageBonus => game_l10n.passiveMagicBonus(percent), PassiveType.magicDamageBonus => game_l10n.passiveMagicBonus(percent),
PassiveType.criticalBonus => game_l10n.passiveCritBonus(percent), PassiveType.criticalBonus => game_l10n.passiveCritBonus(percent),
PassiveType.expBonus => passive.description, PassiveType.expBonus => passive.description,
PassiveType.deathEquipmentPreserve => passive.description,
}; };
} }

View File

@@ -64,7 +64,6 @@ class _SettingsScreenState extends State<SettingsScreen> {
bool _isLoading = true; bool _isLoading = true;
// 디버그 설정 상태 (Phase 8) // 디버그 설정 상태 (Phase 8)
bool _debugAdEnabled = true;
bool _debugIapSimulated = false; bool _debugIapSimulated = false;
int _debugOfflineHours = 0; int _debugOfflineHours = 0;
@@ -80,7 +79,6 @@ class _SettingsScreenState extends State<SettingsScreen> {
// 디버그 설정 로드 (Phase 8) // 디버그 설정 로드 (Phase 8)
final debugSettings = DebugSettingsService.instance; final debugSettings = DebugSettingsService.instance;
final adEnabled = debugSettings.adEnabled;
final iapSimulated = debugSettings.iapSimulated; final iapSimulated = debugSettings.iapSimulated;
final offlineHours = debugSettings.offlineHours; final offlineHours = debugSettings.offlineHours;
@@ -88,7 +86,6 @@ class _SettingsScreenState extends State<SettingsScreen> {
setState(() { setState(() {
_bgmVolume = bgm; _bgmVolume = bgm;
_sfxVolume = sfx; _sfxVolume = sfx;
_debugAdEnabled = adEnabled;
_debugIapSimulated = iapSimulated; _debugIapSimulated = iapSimulated;
_debugOfflineHours = offlineHours; _debugOfflineHours = offlineHours;
_isLoading = false; _isLoading = false;
@@ -304,7 +301,11 @@ class _SettingsScreenState extends State<SettingsScreen> {
// 헤더 // 헤더
Row( Row(
children: [ children: [
Icon(Icons.bug_report, color: RetroColors.hpOf(context), size: 16), Icon(
Icons.bug_report,
color: RetroColors.hpOf(context),
size: 16,
),
const SizedBox(width: 8), const SizedBox(width: 8),
Text( Text(
'DEVELOPER TOOLS', 'DEVELOPER TOOLS',
@@ -318,19 +319,6 @@ class _SettingsScreenState extends State<SettingsScreen> {
), ),
const SizedBox(height: 16), const SizedBox(height: 16),
// 광고 ON/OFF 토글
_RetroDebugToggle(
icon: Icons.ad_units,
label: 'ADS ENABLED',
description: 'OFF: 광고 버튼 클릭 시 바로 보상',
value: _debugAdEnabled,
onChanged: (value) async {
await DebugSettingsService.instance.setAdEnabled(value);
setState(() => _debugAdEnabled = value);
},
),
const SizedBox(height: 12),
// IAP 시뮬레이션 토글 // IAP 시뮬레이션 토글
_RetroDebugToggle( _RetroDebugToggle(
icon: Icons.shopping_cart, icon: Icons.shopping_cart,
@@ -448,7 +436,8 @@ class _SettingsScreenState extends State<SettingsScreen> {
context: context, context: context,
builder: (context) => _RetroConfirmDialog( builder: (context) => _RetroConfirmDialog(
title: 'CREATE TEST CHARACTER?', title: 'CREATE TEST CHARACTER?',
message: '현재 캐릭터가 레벨 100으로 변환되어\n' message:
'현재 캐릭터가 레벨 100으로 변환되어\n'
'명예의 전당에 등록됩니다.\n\n' '명예의 전당에 등록됩니다.\n\n'
'⚠️ 현재 세이브 파일이 삭제됩니다.\n' '⚠️ 현재 세이브 파일이 삭제됩니다.\n'
'이 작업은 되돌릴 수 없습니다.', '이 작업은 되돌릴 수 없습니다.',
@@ -480,11 +469,7 @@ class _RetroSectionTitle extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Row( return Row(
children: [ children: [
Container( Container(width: 4, height: 14, color: RetroColors.goldOf(context)),
width: 4,
height: 14,
color: RetroColors.goldOf(context),
),
const SizedBox(width: 8), const SizedBox(width: 8),
Text( Text(
title.toUpperCase(), title.toUpperCase(),