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

@@ -7,7 +7,6 @@ import 'dart:math' as math;
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import '../providers/subscription_provider.dart';
import '../providers/category_provider.dart';
import '../models/category_model.dart';
import '../services/sms_service.dart';
import '../services/subscription_url_matcher.dart';
import '../services/exchange_rate_service.dart';
@@ -495,7 +494,7 @@ class _AddSubscriptionScreenState extends State<AddSubscriptionScreen>
);
if (mounted) {
Navigator.pop(context);
Navigator.pop(context, true); // 성공 여부 반환
}
} catch (e) {
setState(() {
@@ -536,11 +535,11 @@ class _AddSubscriptionScreenState extends State<AddSubscriptionScreen>
preferredSize: const Size.fromHeight(60),
child: Container(
decoration: BoxDecoration(
color: Colors.white.withOpacity(appBarOpacity),
color: Colors.white.withValues(alpha: appBarOpacity),
boxShadow: appBarOpacity > 0.6
? [
BoxShadow(
color: Colors.black.withOpacity(0.1 * appBarOpacity),
color: Colors.black.withValues(alpha: 0.1 * appBarOpacity),
spreadRadius: 1,
blurRadius: 8,
offset: const Offset(0, 4),
@@ -561,7 +560,7 @@ class _AddSubscriptionScreenState extends State<AddSubscriptionScreen>
shadows: appBarOpacity > 0.6
? [
Shadow(
color: Colors.black.withOpacity(0.2),
color: Colors.black.withValues(alpha: 0.2),
offset: const Offset(0, 1),
blurRadius: 2,
)
@@ -626,7 +625,7 @@ class _AddSubscriptionScreenState extends State<AddSubscriptionScreen>
),
boxShadow: [
BoxShadow(
color: _gradientColors[0].withOpacity(0.3),
color: _gradientColors[0].withValues(alpha: 0.3),
blurRadius: 20,
spreadRadius: 0,
offset: const Offset(0, 8),
@@ -638,7 +637,7 @@ class _AddSubscriptionScreenState extends State<AddSubscriptionScreen>
Container(
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
color: Colors.white.withOpacity(0.2),
color: Colors.white.withValues(alpha: 0.2),
borderRadius: BorderRadius.circular(16),
),
child: const Icon(
@@ -741,7 +740,7 @@ class _AddSubscriptionScreenState extends State<AddSubscriptionScreen>
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(16),
color: _currentEditingField == 0
? const Color(0xFF3B82F6).withOpacity(0.1)
? const Color(0xFF3B82F6).withValues(alpha: 0.1)
: Colors.transparent,
),
padding: const EdgeInsets.all(8),
@@ -786,7 +785,7 @@ class _AddSubscriptionScreenState extends State<AddSubscriptionScreen>
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
borderSide: BorderSide(
color: Colors.grey.withOpacity(0.2),
color: Colors.grey.withValues(alpha: 0.2),
),
),
focusedBorder: OutlineInputBorder(
@@ -821,7 +820,7 @@ class _AddSubscriptionScreenState extends State<AddSubscriptionScreen>
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(16),
color: _currentEditingField == 1
? const Color(0xFF3B82F6).withOpacity(0.1)
? const Color(0xFF3B82F6).withValues(alpha: 0.1)
: Colors.transparent,
),
padding: const EdgeInsets.all(8),
@@ -922,7 +921,7 @@ class _AddSubscriptionScreenState extends State<AddSubscriptionScreen>
BorderRadius.circular(12),
borderSide: BorderSide(
color:
Colors.grey.withOpacity(0.2),
Colors.grey.withValues(alpha: 0.2),
),
),
focusedBorder: OutlineInputBorder(
@@ -979,7 +978,7 @@ class _AddSubscriptionScreenState extends State<AddSubscriptionScreen>
border: Border.all(
color: _currentEditingField == 1
? const Color(0xFF3B82F6)
: Colors.grey.withOpacity(
: Colors.grey.withValues(alpha:
0.4), // 포커스 없을 때 더 진한 회색
width: _currentEditingField == 1
? 2
@@ -997,7 +996,7 @@ class _AddSubscriptionScreenState extends State<AddSubscriptionScreen>
border: Border(
right: BorderSide(
color: Colors.grey
.withOpacity(0.2),
.withValues(alpha: 0.2),
width: 1,
),
),
@@ -1248,7 +1247,7 @@ class _AddSubscriptionScreenState extends State<AddSubscriptionScreen>
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(16),
color: _currentEditingField == 2
? const Color(0xFF3B82F6).withOpacity(0.1)
? const Color(0xFF3B82F6).withValues(alpha: 0.1)
: Colors.transparent,
),
padding: const EdgeInsets.all(8),
@@ -1285,7 +1284,7 @@ class _AddSubscriptionScreenState extends State<AddSubscriptionScreen>
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
borderSide: BorderSide(
color: Colors.grey.withOpacity(0.2),
color: Colors.grey.withValues(alpha: 0.2),
),
),
focusedBorder: OutlineInputBorder(
@@ -1336,7 +1335,7 @@ class _AddSubscriptionScreenState extends State<AddSubscriptionScreen>
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(16),
color: _currentEditingField == 3
? const Color(0xFF3B82F6).withOpacity(0.1)
? const Color(0xFF3B82F6).withValues(alpha: 0.1)
: Colors.transparent,
),
padding: const EdgeInsets.all(8),
@@ -1397,7 +1396,7 @@ class _AddSubscriptionScreenState extends State<AddSubscriptionScreen>
border: Border.all(
color: _nextBillingDate == null
? Colors.red
: Colors.grey.withOpacity(0.2),
: Colors.grey.withValues(alpha: 0.2),
),
borderRadius: BorderRadius.circular(12),
color: Colors.white,
@@ -1437,7 +1436,7 @@ class _AddSubscriptionScreenState extends State<AddSubscriptionScreen>
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(16),
color: _currentEditingField == 4
? const Color(0xFF3B82F6).withOpacity(0.1)
? const Color(0xFF3B82F6).withValues(alpha: 0.1)
: Colors.transparent,
),
padding: const EdgeInsets.all(8),
@@ -1476,7 +1475,7 @@ class _AddSubscriptionScreenState extends State<AddSubscriptionScreen>
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
borderSide: BorderSide(
color: Colors.grey.withOpacity(0.2),
color: Colors.grey.withValues(alpha: 0.2),
),
),
focusedBorder: OutlineInputBorder(
@@ -1504,7 +1503,7 @@ class _AddSubscriptionScreenState extends State<AddSubscriptionScreen>
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(16),
color: _currentEditingField == 5
? const Color(0xFF3B82F6).withOpacity(0.1)
? const Color(0xFF3B82F6).withValues(alpha: 0.1)
: Colors.transparent,
),
padding: const EdgeInsets.all(8),
@@ -1538,7 +1537,7 @@ class _AddSubscriptionScreenState extends State<AddSubscriptionScreen>
decoration: BoxDecoration(
border: Border.all(
color:
Colors.grey.withOpacity(0.2),
Colors.grey.withValues(alpha: 0.2),
),
borderRadius:
BorderRadius.circular(12),
@@ -1598,7 +1597,7 @@ class _AddSubscriptionScreenState extends State<AddSubscriptionScreen>
borderRadius:
BorderRadius.circular(12),
borderSide: BorderSide(
color: Colors.grey.withOpacity(0.2),
color: Colors.grey.withValues(alpha: 0.2),
),
),
focusedBorder: OutlineInputBorder(
@@ -1667,7 +1666,7 @@ class _AddSubscriptionScreenState extends State<AddSubscriptionScreen>
border: Border.all(
color: _isEventActive
? const Color(0xFF3B82F6)
: Colors.grey.withOpacity(0.2),
: Colors.grey.withValues(alpha: 0.2),
width: _isEventActive ? 2 : 1,
),
),
@@ -1761,7 +1760,7 @@ class _AddSubscriptionScreenState extends State<AddSubscriptionScreen>
child: Container(
padding: const EdgeInsets.all(12),
decoration: BoxDecoration(
border: Border.all(color: Colors.grey.withOpacity(0.3)),
border: Border.all(color: Colors.grey.withValues(alpha: 0.3)),
borderRadius: BorderRadius.circular(12),
),
child: Column(
@@ -1825,7 +1824,7 @@ class _AddSubscriptionScreenState extends State<AddSubscriptionScreen>
child: Container(
padding: const EdgeInsets.all(12),
decoration: BoxDecoration(
border: Border.all(color: Colors.grey.withOpacity(0.3)),
border: Border.all(color: Colors.grey.withValues(alpha: 0.3)),
borderRadius: BorderRadius.circular(12),
),
child: Column(
@@ -1889,7 +1888,7 @@ class _AddSubscriptionScreenState extends State<AddSubscriptionScreen>
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
borderSide: BorderSide(
color: Colors.grey.withOpacity(0.2),
color: Colors.grey.withValues(alpha: 0.2),
),
),
focusedBorder: OutlineInputBorder(
@@ -1967,15 +1966,15 @@ class _AddSubscriptionScreenState extends State<AddSubscriptionScreen>
style: ElevatedButton.styleFrom(
backgroundColor: const Color(0xFF3B82F6),
foregroundColor: Colors.white,
disabledBackgroundColor: Colors.grey.withOpacity(0.3),
disabledBackgroundColor: Colors.grey.withValues(alpha: 0.3),
disabledForegroundColor:
Colors.white.withOpacity(0.5),
Colors.white.withValues(alpha: 0.5),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16),
),
padding: const EdgeInsets.symmetric(vertical: 16),
elevation: _isSaveHovered ? 8 : 4,
shadowColor: const Color(0xFF3B82F6).withOpacity(0.5),
shadowColor: const Color(0xFF3B82F6).withValues(alpha: 0.5),
),
child: _isLoading
? const SizedBox(