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:
@@ -1,12 +1,15 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'dart:math' as math;
|
||||
import '../models/subscription_model.dart';
|
||||
import '../screens/detail_screen.dart';
|
||||
import 'website_icon.dart';
|
||||
import 'app_navigator.dart';
|
||||
import '../theme/app_colors.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import '../providers/subscription_provider.dart';
|
||||
import 'glassmorphism_card.dart';
|
||||
|
||||
class SubscriptionCard extends StatefulWidget {
|
||||
final SubscriptionModel subscription;
|
||||
@@ -230,67 +233,30 @@ class _SubscriptionCardState extends State<SubscriptionCard>
|
||||
color: Colors.transparent,
|
||||
child: InkWell(
|
||||
onTap: () async {
|
||||
final result = await Navigator.push(
|
||||
context,
|
||||
PageRouteBuilder(
|
||||
pageBuilder: (context, animation, secondaryAnimation) =>
|
||||
DetailScreen(subscription: widget.subscription),
|
||||
transitionsBuilder:
|
||||
(context, animation, secondaryAnimation, child) {
|
||||
const begin = Offset(0.0, 0.05);
|
||||
const end = Offset.zero;
|
||||
const curve = Curves.easeOutCubic;
|
||||
|
||||
var tween = Tween(begin: begin, end: end)
|
||||
.chain(CurveTween(curve: curve));
|
||||
|
||||
var fadeAnimation =
|
||||
Tween<double>(begin: 0.6, end: 1.0)
|
||||
.chain(CurveTween(curve: curve))
|
||||
.animate(animation);
|
||||
|
||||
return FadeTransition(
|
||||
opacity: fadeAnimation,
|
||||
child: SlideTransition(
|
||||
position: animation.drive(tween),
|
||||
child: child,
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
|
||||
if (result == true) {
|
||||
// 변경 사항이 있을 경우 미리 저장된 Provider 참조를 사용하여 구독 목록 갱신
|
||||
await _subscriptionProvider.refreshSubscriptions();
|
||||
|
||||
// 메인 화면의 State를 갱신하기 위해 미세한 지연 후 다시 한번 알림
|
||||
// mounted 상태를 확인하여 dispose된 위젯에서 Provider를 참조하지 않도록 합니다.
|
||||
Future.delayed(const Duration(milliseconds: 100), () {
|
||||
// 위젯이 아직 마운트 상태인지 확인하고, 미리 저장된 Provider 참조 사용
|
||||
if (mounted) {
|
||||
_subscriptionProvider.notifyListeners();
|
||||
}
|
||||
});
|
||||
}
|
||||
await AppNavigator.toDetail(context, widget.subscription);
|
||||
},
|
||||
splashColor: AppColors.primaryColor.withOpacity(0.1),
|
||||
highlightColor: AppColors.primaryColor.withOpacity(0.05),
|
||||
splashColor: AppColors.primaryColor.withValues(alpha: 0.1),
|
||||
highlightColor: AppColors.primaryColor.withValues(alpha: 0.05),
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
child: Container(
|
||||
child: AnimatedGlassmorphismCard(
|
||||
onTap: () {}, // onTap은 이미 InkWell에서 처리됨
|
||||
padding: EdgeInsets.zero,
|
||||
borderRadius: 16,
|
||||
blur: _isHovering ? 15 : 10,
|
||||
child: Container(
|
||||
clipBehavior: Clip.antiAlias,
|
||||
decoration: BoxDecoration(
|
||||
color: cardColor,
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
border: Border.all(
|
||||
color: _isHovering
|
||||
? AppColors.primaryColor.withOpacity(0.3)
|
||||
? AppColors.primaryColor.withValues(alpha: 0.3)
|
||||
: AppColors.borderColor,
|
||||
width: _isHovering ? 1.5 : 0.5,
|
||||
),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: AppColors.primaryColor.withOpacity(
|
||||
color: AppColors.primaryColor.withValues(alpha:
|
||||
0.03 + (0.05 * _hoverController.value)),
|
||||
blurRadius: 8 + (8 * _hoverController.value),
|
||||
spreadRadius: 0,
|
||||
@@ -502,9 +468,9 @@ class _SubscriptionCardState extends State<SubscriptionCard>
|
||||
decoration: BoxDecoration(
|
||||
color: isNearBilling
|
||||
? AppColors.warningColor
|
||||
.withOpacity(0.1)
|
||||
.withValues(alpha: 0.1)
|
||||
: AppColors.successColor
|
||||
.withOpacity(0.1),
|
||||
.withValues(alpha: 0.1),
|
||||
borderRadius:
|
||||
BorderRadius.circular(12),
|
||||
),
|
||||
@@ -551,7 +517,7 @@ class _SubscriptionCardState extends State<SubscriptionCard>
|
||||
vertical: 2,
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xFFFF6B6B).withOpacity(0.1),
|
||||
color: const Color(0xFFFF6B6B).withValues(alpha: 0.1),
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
child: Row(
|
||||
@@ -607,6 +573,7 @@ class _SubscriptionCardState extends State<SubscriptionCard>
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user