- Murattal: Spotify-style 5-button controls [Shuffle, Prev, Play, Next, Playlist] - Murattal: Animated 7-bar equalizer visualization in player circle - Murattal: Unsplash API background with frosted glass player overlay - Murattal: Transparent AppBar with backdrop blur - Murattal: Surah playlist bottom sheet with full 114 Surah list - Murattal: Auto-play disabled on screen open, enabled on navigation - Murattal: Shuffle mode for random Surah playback - Murattal: Photographer attribution per Unsplash guidelines - Dashboard: Auto-scroll prayer schedule to next active prayer - Fix: setState lifecycle errors on Reading & Murattal screens - Setup: flutter_dotenv, cached_network_image, url_launcher deps
70 lines
1.8 KiB
Dart
70 lines
1.8 KiB
Dart
import 'package:flutter/material.dart';
|
||
import '../../app/theme/app_colors.dart';
|
||
|
||
/// Reusable linear progress bar with primary fill.
|
||
/// Configurable height, borderRadius, and value (0.0–1.0).
|
||
class AppProgressBar extends StatelessWidget {
|
||
const AppProgressBar({
|
||
super.key,
|
||
required this.value,
|
||
this.height = 12.0,
|
||
this.borderRadius,
|
||
this.backgroundColor,
|
||
this.fillColor,
|
||
});
|
||
|
||
/// Progress value from 0.0 to 1.0.
|
||
final double value;
|
||
|
||
/// Height of the bar. Default 12dp.
|
||
final double height;
|
||
|
||
/// Border radius. Defaults to stadium (full).
|
||
final BorderRadius? borderRadius;
|
||
|
||
/// Background track color. Defaults to white/10 (dark) or primary/10 (light).
|
||
final Color? backgroundColor;
|
||
|
||
/// Fill color. Defaults to AppColors.primary.
|
||
final Color? fillColor;
|
||
|
||
@override
|
||
Widget build(BuildContext context) {
|
||
final isDark = Theme.of(context).brightness == Brightness.dark;
|
||
final trackColor = backgroundColor ??
|
||
(isDark
|
||
? Colors.white.withValues(alpha: 0.1)
|
||
: AppColors.primary.withValues(alpha: 0.1));
|
||
final fill = fillColor ?? AppColors.primary;
|
||
final radius = borderRadius ?? BorderRadius.circular(height / 2);
|
||
|
||
return ClipRRect(
|
||
borderRadius: radius,
|
||
child: SizedBox(
|
||
height: height,
|
||
child: Stack(
|
||
children: [
|
||
// Track
|
||
Container(
|
||
decoration: BoxDecoration(
|
||
color: trackColor,
|
||
borderRadius: radius,
|
||
),
|
||
),
|
||
// Fill
|
||
FractionallySizedBox(
|
||
widthFactor: value.clamp(0.0, 1.0),
|
||
child: Container(
|
||
decoration: BoxDecoration(
|
||
color: fill,
|
||
borderRadius: radius,
|
||
),
|
||
),
|
||
),
|
||
],
|
||
),
|
||
),
|
||
);
|
||
}
|
||
}
|