Reading State GetX
⚠️ Important: Each
Obxmust read.valuedirectly from a controller inside its builder. Do not wrap a whole widget inObxif Rx values are read in a deeperbuild— GetX will throw an error.
final c = QuranAudio.surahController;
// ✅ Correct — .value is read directly inside Obx
Obx(() => Text(
c.isPlaying.value ? 'Playing' : 'Paused',
));
Obx(() => Text('Surah: ${c.currentSurahNumber.value}'));
Progress bar & reactive card
// Progress bar via StreamBuilder (no Obx needed)
StreamBuilder<PositionData>(
stream: QuranAudio.positionDataStream,
builder: (context, snap) {
final d = snap.data;
return Slider(
value: d?.position.inSeconds.toDouble() ?? 0,
max: d?.duration.inSeconds.toDouble() ?? 1,
onChanged: (v) => QuranAudio.seek(Duration(seconds: v.toInt())),
);
},
);
// A reactive now-playing card
class NowPlayingCard extends StatelessWidget {
Widget build(BuildContext context) {
final surahC = QuranAudio.surahController;
final ayahC = QuranAudio.ayahController;
return Obx(() {
final surahNo = surahC.currentSurahNumber.value;
final ayahNo = ayahC.currentAyahInSurah.value;
final playing = surahC.isPlaying.value || ayahC.isPlaying.value;
final meta = QuranAudio.surah(surahNo);
return Card(
child: ListTile(
title: Text(meta.name),
subtitle: Text(playing ? 'Playing' : 'Paused'),
trailing: Text('$ayahNo / ${meta.ayahCount}'),
),
);
});
}
}