feat: Murattal player enhancements & prayer schedule auto-scroll
- 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
This commit is contained in:
58
lib/core/widgets/ios_toggle.dart
Normal file
58
lib/core/widgets/ios_toggle.dart
Normal file
@@ -0,0 +1,58 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import '../../app/theme/app_colors.dart';
|
||||
|
||||
/// Custom iOS-style toggle switch (51×31dp) per PRD §6.9.
|
||||
/// Uses AnimatedContainer + GestureDetector for smooth animation.
|
||||
class IosToggle extends StatelessWidget {
|
||||
const IosToggle({
|
||||
super.key,
|
||||
required this.value,
|
||||
required this.onChanged,
|
||||
});
|
||||
|
||||
final bool value;
|
||||
final ValueChanged<bool> onChanged;
|
||||
|
||||
static const double _width = 51.0;
|
||||
static const double _height = 31.0;
|
||||
static const double _thumbSize = 27.0;
|
||||
static const double _thumbPadding = 2.0;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return GestureDetector(
|
||||
onTap: () => onChanged(!value),
|
||||
child: AnimatedContainer(
|
||||
duration: const Duration(milliseconds: 200),
|
||||
curve: Curves.easeInOut,
|
||||
width: _width,
|
||||
height: _height,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(_height / 2),
|
||||
color: value ? AppColors.primary : AppColors.cream,
|
||||
),
|
||||
child: AnimatedAlign(
|
||||
duration: const Duration(milliseconds: 200),
|
||||
curve: Curves.easeInOut,
|
||||
alignment: value ? Alignment.centerRight : Alignment.centerLeft,
|
||||
child: Container(
|
||||
width: _thumbSize,
|
||||
height: _thumbSize,
|
||||
margin: const EdgeInsets.all(_thumbPadding),
|
||||
decoration: BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
color: Colors.white,
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.black.withValues(alpha: 0.15),
|
||||
blurRadius: 4,
|
||||
offset: const Offset(0, 2),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user