Your commit message here
This commit is contained in:
@@ -4,7 +4,11 @@ import 'dart:math' as math;
|
||||
import '../theme/app_theme.dart';
|
||||
import '../models/cycle_entry.dart';
|
||||
|
||||
<<<<<<< HEAD
|
||||
class CycleRing extends StatelessWidget {
|
||||
=======
|
||||
class CycleRing extends StatefulWidget {
|
||||
>>>>>>> 6742220 (Your commit message here)
|
||||
final int dayOfCycle;
|
||||
final int totalDays;
|
||||
final CyclePhase phase;
|
||||
@@ -17,6 +21,7 @@ class CycleRing extends StatelessWidget {
|
||||
});
|
||||
|
||||
@override
|
||||
<<<<<<< HEAD
|
||||
Widget build(BuildContext context) {
|
||||
final progress = dayOfCycle / totalDays;
|
||||
final daysUntilNextPeriod = totalDays - dayOfCycle;
|
||||
@@ -82,12 +87,128 @@ class CycleRing extends StatelessWidget {
|
||||
style: GoogleFonts.outfit(
|
||||
fontSize: 12,
|
||||
color: AppColors.warmGray,
|
||||
=======
|
||||
State<CycleRing> createState() => _CycleRingState();
|
||||
}
|
||||
|
||||
class _CycleRingState extends State<CycleRing> with SingleTickerProviderStateMixin {
|
||||
late AnimationController _controller;
|
||||
late Animation<double> _animation;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_controller = AnimationController(
|
||||
vsync: this,
|
||||
duration: const Duration(milliseconds: 1500),
|
||||
);
|
||||
_animation = CurvedAnimation(
|
||||
parent: _controller,
|
||||
curve: Curves.easeOutCubic,
|
||||
);
|
||||
_controller.forward();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_controller.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final targetProgress = widget.dayOfCycle / widget.totalDays;
|
||||
final daysUntilNextPeriod = widget.totalDays - widget.dayOfCycle;
|
||||
final isDark = Theme.of(context).brightness == Brightness.dark;
|
||||
|
||||
return AnimatedBuilder(
|
||||
animation: _animation,
|
||||
builder: (context, child) {
|
||||
final currentProgress = targetProgress * _animation.value;
|
||||
|
||||
return SizedBox(
|
||||
width: 220,
|
||||
height: 220,
|
||||
child: Stack(
|
||||
alignment: Alignment.center,
|
||||
children: [
|
||||
// Background ring
|
||||
CustomPaint(
|
||||
size: const Size(220, 220),
|
||||
painter: _CycleRingPainter(
|
||||
progress: currentProgress,
|
||||
phase: widget.phase,
|
||||
isDark: isDark,
|
||||
),
|
||||
),
|
||||
|
||||
// Center content with scale and fade animation
|
||||
Transform.scale(
|
||||
scale: 0.8 + (0.2 * _animation.value),
|
||||
child: Opacity(
|
||||
opacity: _animation.value,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Text(
|
||||
'Day ${widget.dayOfCycle}',
|
||||
style: Theme.of(context).textTheme.displayMedium?.copyWith(
|
||||
fontSize: 32,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Theme.of(context).colorScheme.onSurface,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 4),
|
||||
Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 6),
|
||||
decoration: BoxDecoration(
|
||||
color: _getPhaseColor(widget.phase).withOpacity(isDark ? 0.3 : 0.2),
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
border: isDark ? Border.all(color: _getPhaseColor(widget.phase).withOpacity(0.5)) : null,
|
||||
),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Text(
|
||||
widget.phase.emoji,
|
||||
style: const TextStyle(fontSize: 14),
|
||||
),
|
||||
const SizedBox(width: 6),
|
||||
Text(
|
||||
widget.phase.label,
|
||||
style: GoogleFonts.outfit(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: isDark ? Colors.white : _getPhaseColor(widget.phase),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
Text(
|
||||
daysUntilNextPeriod > 0
|
||||
? '$daysUntilNextPeriod days until period'
|
||||
: 'Period expected',
|
||||
style: Theme.of(context).textTheme.bodySmall?.copyWith(
|
||||
fontSize: 12,
|
||||
color: Theme.of(context).colorScheme.onSurfaceVariant,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
>>>>>>> 6742220 (Your commit message here)
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
<<<<<<< HEAD
|
||||
],
|
||||
),
|
||||
=======
|
||||
);
|
||||
},
|
||||
>>>>>>> 6742220 (Your commit message here)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -108,8 +229,18 @@ class CycleRing extends StatelessWidget {
|
||||
class _CycleRingPainter extends CustomPainter {
|
||||
final double progress;
|
||||
final CyclePhase phase;
|
||||
<<<<<<< HEAD
|
||||
|
||||
_CycleRingPainter({required this.progress, required this.phase});
|
||||
=======
|
||||
final bool isDark;
|
||||
|
||||
_CycleRingPainter({
|
||||
required this.progress,
|
||||
required this.phase,
|
||||
required this.isDark,
|
||||
});
|
||||
>>>>>>> 6742220 (Your commit message here)
|
||||
|
||||
@override
|
||||
void paint(Canvas canvas, Size size) {
|
||||
@@ -119,7 +250,11 @@ class _CycleRingPainter extends CustomPainter {
|
||||
|
||||
// Background arc
|
||||
final bgPaint = Paint()
|
||||
<<<<<<< HEAD
|
||||
..color = AppColors.lightGray.withOpacity(0.2)
|
||||
=======
|
||||
..color = (isDark ? Colors.white : AppColors.lightGray).withOpacity(isDark ? 0.05 : 0.1)
|
||||
>>>>>>> 6742220 (Your commit message here)
|
||||
..style = PaintingStyle.stroke
|
||||
..strokeWidth = strokeWidth
|
||||
..strokeCap = StrokeCap.round;
|
||||
@@ -152,7 +287,11 @@ class _CycleRingPainter extends CustomPainter {
|
||||
final dotY = center.dy + radius * math.sin(dotAngle);
|
||||
|
||||
final dotPaint = Paint()
|
||||
<<<<<<< HEAD
|
||||
..color = Colors.white
|
||||
=======
|
||||
..color = isDark ? const Color(0xFF1E1E1E) : Colors.white
|
||||
>>>>>>> 6742220 (Your commit message here)
|
||||
..style = PaintingStyle.fill;
|
||||
|
||||
final dotBorderPaint = Paint()
|
||||
|
||||
Reference in New Issue
Block a user