feat(front): 프론트 화면 개선 및 설정 저장소 추가

- front_screen_animation.dart: 프론트 화면 애니메이션 추가
- settings_repository.dart: 설정 저장소 구현
- front/widgets/: 프론트 화면 위젯 분리
- mobile_carousel_layout.dart: 모바일 레이아웃 개선
- app.dart: 앱 설정 개선
- game_text_l10n.dart: 텍스트 추가
This commit is contained in:
JiWoong Sul
2025-12-23 18:52:46 +09:00
parent e6af7dd91a
commit 549851f693
10 changed files with 722 additions and 183 deletions

View File

@@ -37,6 +37,8 @@ class MobileCarouselLayout extends StatefulWidget {
required this.onLanguageChange,
required this.onDeleteSaveAndNewGame,
this.specialAnimation,
this.currentThemeMode = ThemeMode.system,
this.onThemeModeChange,
});
final GameState state;
@@ -51,6 +53,8 @@ class MobileCarouselLayout extends StatefulWidget {
final void Function(String locale) onLanguageChange;
final VoidCallback onDeleteSaveAndNewGame;
final AsciiAnimationType? specialAnimation;
final ThemeMode currentThemeMode;
final void Function(ThemeMode mode)? onThemeModeChange;
@override
State<MobileCarouselLayout> createState() => _MobileCarouselLayoutState();
@@ -94,6 +98,66 @@ class _MobileCarouselLayoutState extends State<MobileCarouselLayout> {
return l10n.languageEnglish;
}
/// 현재 테마명 가져오기
String _getCurrentThemeName() {
return switch (widget.currentThemeMode) {
ThemeMode.light => l10n.themeLight,
ThemeMode.dark => l10n.themeDark,
ThemeMode.system => l10n.themeSystem,
};
}
/// 테마 아이콘 가져오기
IconData _getThemeIcon() {
return switch (widget.currentThemeMode) {
ThemeMode.light => Icons.light_mode,
ThemeMode.dark => Icons.dark_mode,
ThemeMode.system => Icons.brightness_auto,
};
}
/// 테마 선택 다이얼로그 표시
void _showThemeDialog(BuildContext context) {
showDialog<void>(
context: context,
builder: (context) => AlertDialog(
title: Text(l10n.menuTheme),
content: Column(
mainAxisSize: MainAxisSize.min,
children: [
_buildThemeOption(context, ThemeMode.system, l10n.themeSystem),
_buildThemeOption(context, ThemeMode.light, l10n.themeLight),
_buildThemeOption(context, ThemeMode.dark, l10n.themeDark),
],
),
),
);
}
Widget _buildThemeOption(
BuildContext context,
ThemeMode mode,
String label,
) {
final isSelected = widget.currentThemeMode == mode;
return ListTile(
leading: Icon(
isSelected ? Icons.radio_button_checked : Icons.radio_button_unchecked,
color: isSelected ? Theme.of(context).colorScheme.primary : null,
),
title: Text(
label,
style: TextStyle(
fontWeight: isSelected ? FontWeight.bold : FontWeight.normal,
),
),
onTap: () {
Navigator.pop(context); // 다이얼로그 닫기
widget.onThemeModeChange?.call(mode);
},
);
}
/// 언어 선택 다이얼로그 표시
void _showLanguageDialog(BuildContext context) {
showDialog<void>(
@@ -242,6 +306,24 @@ class _MobileCarouselLayoutState extends State<MobileCarouselLayout> {
},
),
// 테마 변경
if (widget.onThemeModeChange != null)
ListTile(
leading: Icon(
_getThemeIcon(),
color: Colors.purple,
),
title: Text(l10n.menuTheme),
trailing: Text(
_getCurrentThemeName(),
style: TextStyle(color: Theme.of(context).colorScheme.primary),
),
onTap: () {
Navigator.pop(context);
_showThemeDialog(context);
},
),
const Divider(),
// 저장