feat(app): add manual entry and sharing flows
This commit is contained in:
@@ -12,11 +12,12 @@ class SplashScreen extends StatefulWidget {
|
||||
State<SplashScreen> createState() => _SplashScreenState();
|
||||
}
|
||||
|
||||
class _SplashScreenState extends State<SplashScreen> with TickerProviderStateMixin {
|
||||
class _SplashScreenState extends State<SplashScreen>
|
||||
with TickerProviderStateMixin {
|
||||
late List<AnimationController> _foodControllers;
|
||||
late AnimationController _questionMarkController;
|
||||
late AnimationController _centerIconController;
|
||||
|
||||
|
||||
final List<IconData> foodIcons = [
|
||||
Icons.rice_bowl,
|
||||
Icons.ramen_dining,
|
||||
@@ -28,14 +29,14 @@ class _SplashScreenState extends State<SplashScreen> with TickerProviderStateMix
|
||||
Icons.icecream,
|
||||
Icons.bakery_dining,
|
||||
];
|
||||
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_initializeAnimations();
|
||||
_navigateToHome();
|
||||
}
|
||||
|
||||
|
||||
void _initializeAnimations() {
|
||||
// 음식 아이콘 애니메이션 (여러 개)
|
||||
_foodControllers = List.generate(
|
||||
@@ -45,31 +46,33 @@ class _SplashScreenState extends State<SplashScreen> with TickerProviderStateMix
|
||||
vsync: this,
|
||||
)..repeat(reverse: true),
|
||||
);
|
||||
|
||||
|
||||
// 물음표 애니메이션
|
||||
_questionMarkController = AnimationController(
|
||||
duration: const Duration(milliseconds: 500),
|
||||
vsync: this,
|
||||
)..repeat();
|
||||
|
||||
|
||||
// 중앙 아이콘 애니메이션
|
||||
_centerIconController = AnimationController(
|
||||
duration: const Duration(seconds: 1),
|
||||
vsync: this,
|
||||
)..repeat(reverse: true);
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final isDark = Theme.of(context).brightness == Brightness.dark;
|
||||
|
||||
|
||||
return Scaffold(
|
||||
backgroundColor: isDark ? AppColors.darkBackground : AppColors.lightBackground,
|
||||
backgroundColor: isDark
|
||||
? AppColors.darkBackground
|
||||
: AppColors.lightBackground,
|
||||
body: Stack(
|
||||
children: [
|
||||
// 랜덤 위치 음식 아이콘들
|
||||
..._buildFoodIcons(),
|
||||
|
||||
|
||||
// 중앙 컨텐츠
|
||||
Center(
|
||||
child: Column(
|
||||
@@ -86,23 +89,25 @@ class _SplashScreenState extends State<SplashScreen> with TickerProviderStateMix
|
||||
child: Icon(
|
||||
Icons.restaurant_menu,
|
||||
size: 80,
|
||||
color: isDark ? AppColors.darkPrimary : AppColors.lightPrimary,
|
||||
color: isDark
|
||||
? AppColors.darkPrimary
|
||||
: AppColors.lightPrimary,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
|
||||
|
||||
// 앱 타이틀
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Text(
|
||||
'오늘 뭐 먹Z',
|
||||
style: AppTypography.heading1(isDark),
|
||||
),
|
||||
Text('오늘 뭐 먹Z', style: AppTypography.heading1(isDark)),
|
||||
AnimatedBuilder(
|
||||
animation: _questionMarkController,
|
||||
builder: (context, child) {
|
||||
final questionMarks = '?' * (((_questionMarkController.value * 3).floor() % 3) + 1);
|
||||
final questionMarks =
|
||||
'?' *
|
||||
(((_questionMarkController.value * 3).floor() % 3) +
|
||||
1);
|
||||
return Text(
|
||||
questionMarks,
|
||||
style: AppTypography.heading1(isDark),
|
||||
@@ -114,7 +119,7 @@ class _SplashScreenState extends State<SplashScreen> with TickerProviderStateMix
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
|
||||
// 하단 카피라이트
|
||||
Positioned(
|
||||
bottom: 30,
|
||||
@@ -123,8 +128,11 @@ class _SplashScreenState extends State<SplashScreen> with TickerProviderStateMix
|
||||
child: Text(
|
||||
AppConstants.appCopyright,
|
||||
style: AppTypography.caption(isDark).copyWith(
|
||||
color: (isDark ? AppColors.darkTextSecondary : AppColors.lightTextSecondary)
|
||||
.withOpacity(0.5),
|
||||
color:
|
||||
(isDark
|
||||
? AppColors.darkTextSecondary
|
||||
: AppColors.lightTextSecondary)
|
||||
.withOpacity(0.5),
|
||||
),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
@@ -133,14 +141,14 @@ class _SplashScreenState extends State<SplashScreen> with TickerProviderStateMix
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
List<Widget> _buildFoodIcons() {
|
||||
final random = math.Random();
|
||||
|
||||
|
||||
return List.generate(foodIcons.length, (index) {
|
||||
final left = random.nextDouble() * 0.8 + 0.1;
|
||||
final top = random.nextDouble() * 0.7 + 0.1;
|
||||
|
||||
|
||||
return Positioned(
|
||||
left: MediaQuery.of(context).size.width * left,
|
||||
top: MediaQuery.of(context).size.height * top,
|
||||
@@ -168,7 +176,7 @@ class _SplashScreenState extends State<SplashScreen> with TickerProviderStateMix
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
void _navigateToHome() {
|
||||
Future.delayed(AppConstants.splashAnimationDuration, () {
|
||||
if (mounted) {
|
||||
@@ -176,7 +184,7 @@ class _SplashScreenState extends State<SplashScreen> with TickerProviderStateMix
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
for (final controller in _foodControllers) {
|
||||
@@ -186,4 +194,4 @@ class _SplashScreenState extends State<SplashScreen> with TickerProviderStateMix
|
||||
_centerIconController.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user