Major UI/UX and architecture improvements

- Implemented new navigation system with NavigationProvider and route management
- Added adaptive theme system with ThemeProvider for better theme handling
- Introduced glassmorphism design elements (app bars, scaffolds, cards)
- Added advanced animations (spring animations, page transitions, staggered lists)
- Implemented performance optimizations (memory manager, lazy loading)
- Refactored Analysis screen into modular components
- Added floating navigation bar with haptic feedback
- Improved subscription cards with swipe actions
- Enhanced skeleton loading with better animations
- Added cached network image support
- Improved overall app architecture and code organization

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
JiWoong Sul
2025-07-10 18:36:57 +09:00
parent 8619e96739
commit 4731288622
55 changed files with 8219 additions and 2149 deletions

View File

@@ -1,24 +1,44 @@
import 'package:flutter/material.dart';
import 'glassmorphism_card.dart';
class SkeletonLoading extends StatelessWidget {
const SkeletonLoading({Key? key}) : super(key: key);
final double? width;
final double? height;
final double borderRadius;
const SkeletonLoading({
Key? key,
this.width,
this.height,
this.borderRadius = 8.0,
}) : super(key: key);
@override
Widget build(BuildContext context) {
// 단일 스켈레톤 아이템이 요청된 경우
if (width != null || height != null) {
return _buildSingleSkeleton();
}
// 기본 전체 화면 스켈레톤
return Column(
children: [
// 요약 카드 스켈레톤
Card(
GlassmorphismCard(
margin: const EdgeInsets.all(16),
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
padding: const EdgeInsets.all(16.0),
blur: 10,
opacity: 0.1,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
width: 100,
height: 24,
color: Colors.grey[300],
decoration: BoxDecoration(
color: Colors.grey[300],
borderRadius: BorderRadius.circular(4),
),
),
const SizedBox(height: 16),
Row(
@@ -29,7 +49,6 @@ class SkeletonLoading extends StatelessWidget {
],
),
],
),
),
),
// 구독 목록 스켈레톤
@@ -37,32 +56,47 @@ class SkeletonLoading extends StatelessWidget {
child: ListView.builder(
itemCount: 5,
itemBuilder: (context, index) {
return Card(
return GlassmorphismCard(
margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
child: ListTile(
contentPadding: const EdgeInsets.all(16),
title: Container(
width: 200,
height: 24,
color: Colors.grey[300],
),
subtitle: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const SizedBox(height: 8),
Container(
width: 150,
height: 16,
color: Colors.grey[300],
padding: const EdgeInsets.all(16),
blur: 10,
opacity: 0.1,
child: Row(
children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
width: 200,
height: 24,
decoration: BoxDecoration(
color: Colors.grey[300],
borderRadius: BorderRadius.circular(4),
),
),
const SizedBox(height: 8),
Container(
width: 150,
height: 16,
decoration: BoxDecoration(
color: Colors.grey[300],
borderRadius: BorderRadius.circular(4),
),
),
const SizedBox(height: 4),
Container(
width: 180,
height: 16,
decoration: BoxDecoration(
color: Colors.grey[300],
borderRadius: BorderRadius.circular(4),
),
),
],
),
const SizedBox(height: 4),
Container(
width: 180,
height: 16,
color: Colors.grey[300],
),
],
),
),
],
),
);
},
@@ -72,6 +106,32 @@ class SkeletonLoading extends StatelessWidget {
);
}
Widget _buildSingleSkeleton() {
return Container(
width: width,
height: height,
decoration: BoxDecoration(
color: Colors.grey[300],
borderRadius: BorderRadius.circular(borderRadius),
),
child: AnimatedContainer(
duration: const Duration(milliseconds: 1500),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(borderRadius),
gradient: LinearGradient(
begin: Alignment.centerLeft,
end: Alignment.centerRight,
colors: [
Colors.grey[300]!,
Colors.grey[100]!,
Colors.grey[300]!,
],
),
),
),
);
}
Widget _buildSkeletonColumn() {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
@@ -79,15 +139,21 @@ class SkeletonLoading extends StatelessWidget {
Container(
width: 80,
height: 16,
color: Colors.grey[300],
decoration: BoxDecoration(
color: Colors.grey[300],
borderRadius: BorderRadius.circular(4),
),
),
const SizedBox(height: 4),
Container(
width: 100,
height: 24,
color: Colors.grey[300],
decoration: BoxDecoration(
color: Colors.grey[300],
borderRadius: BorderRadius.circular(4),
),
),
],
);
}
}
}