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:
dwindown
2026-03-13 15:42:17 +07:00
commit faadc1865d
189 changed files with 23834 additions and 0 deletions

View File

View File

@@ -0,0 +1 @@
// TODO: implement

View File

@@ -0,0 +1,12 @@
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:hive_flutter/hive_flutter.dart';
import '../../data/local/hive_boxes.dart';
import '../../data/local/models/app_settings.dart';
/// Theme mode state provider.
final themeProvider = StateProvider<ThemeMode>((ref) {
final box = Hive.box<AppSettings>(HiveBoxes.settings);
final settings = box.get('default');
return settings?.themeModeIndex == 1 ? ThemeMode.light : ThemeMode.dark;
});

View File

@@ -0,0 +1,54 @@
import 'package:flutter_riverpod/flutter_riverpod.dart';
/// Models an active reading session for Tilawah
class TilawahSession {
final int startSurahId;
final String startSurahName;
final int startVerseId;
const TilawahSession({
required this.startSurahId,
required this.startSurahName,
required this.startVerseId,
});
TilawahSession copyWith({
int? startSurahId,
String? startSurahName,
int? startVerseId,
}) {
return TilawahSession(
startSurahId: startSurahId ?? this.startSurahId,
startSurahName: startSurahName ?? this.startSurahName,
startVerseId: startVerseId ?? this.startVerseId,
);
}
}
/// A state notifier to manage the global start state of a reading session.
/// If state is null, no active tracking is occurring.
class TilawahTrackingNotifier extends StateNotifier<TilawahSession?> {
TilawahTrackingNotifier() : super(null);
/// Start a new tracking session
void startTracking({
required int surahId,
required String surahName,
required int verseId
}) {
state = TilawahSession(
startSurahId: surahId,
startSurahName: surahName,
startVerseId: verseId,
);
}
/// Stop tracking (after recording)
void stopTracking() {
state = null;
}
}
final tilawahTrackingProvider = StateNotifierProvider<TilawahTrackingNotifier, TilawahSession?>((ref) {
return TilawahTrackingNotifier();
});