287 lines
12 KiB
Dart
287 lines
12 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|
import 'package:go_router/go_router.dart';
|
|
import 'package:lucide_icons/lucide_icons.dart';
|
|
import 'package:hive_flutter/hive_flutter.dart';
|
|
import '../../../app/theme/app_colors.dart';
|
|
import '../../../core/widgets/arabic_text.dart';
|
|
import '../../../core/widgets/bottom_sheet_content_padding.dart';
|
|
import '../../../data/local/hive_boxes.dart';
|
|
import '../../../data/local/models/app_settings.dart';
|
|
import '../../../data/local/models/quran_bookmark.dart';
|
|
import '../../../data/services/muslim_api_service.dart';
|
|
|
|
class QuranScreen extends ConsumerStatefulWidget {
|
|
final bool isSimpleModeTab;
|
|
const QuranScreen({super.key, this.isSimpleModeTab = false});
|
|
|
|
@override
|
|
ConsumerState<QuranScreen> createState() => _QuranScreenState();
|
|
}
|
|
|
|
class _QuranScreenState extends ConsumerState<QuranScreen> {
|
|
List<Map<String, dynamic>> _surahs = [];
|
|
String _searchQuery = '';
|
|
bool _loading = true;
|
|
|
|
bool _showLatin = true;
|
|
bool _showTerjemahan = true;
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
_loadSurahs();
|
|
final box = Hive.box<AppSettings>(HiveBoxes.settings);
|
|
final settings = box.get('default') ?? AppSettings();
|
|
_showLatin = settings.showLatin;
|
|
_showTerjemahan = settings.showTerjemahan;
|
|
}
|
|
|
|
Future<void> _loadSurahs() async {
|
|
final data = await MuslimApiService.instance.getAllSurahs();
|
|
if (!mounted) return;
|
|
setState(() {
|
|
_surahs = data;
|
|
_loading = false;
|
|
});
|
|
}
|
|
|
|
void _showDisplaySettings() {
|
|
showModalBottomSheet(
|
|
context: context,
|
|
isScrollControlled: true,
|
|
useSafeArea: true,
|
|
shape: const RoundedRectangleBorder(
|
|
borderRadius: BorderRadius.vertical(top: Radius.circular(20)),
|
|
),
|
|
builder: (ctx) => StatefulBuilder(
|
|
builder: (context, setModalState) {
|
|
return Padding(
|
|
padding: bottomSheetContentPadding(context),
|
|
child: Column(
|
|
mainAxisSize: MainAxisSize.min,
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
const Text(
|
|
'Pengaturan Tampilan',
|
|
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
|
|
),
|
|
const SizedBox(height: 16),
|
|
SwitchListTile(
|
|
title: const Text('Tampilkan Latin'),
|
|
value: _showLatin,
|
|
activeColor: AppColors.primary,
|
|
onChanged: (val) {
|
|
setModalState(() => _showLatin = val);
|
|
setState(() => _showLatin = val);
|
|
final box = Hive.box<AppSettings>(HiveBoxes.settings);
|
|
final settings = box.get('default') ?? AppSettings();
|
|
settings.showLatin = val;
|
|
settings.save();
|
|
},
|
|
),
|
|
SwitchListTile(
|
|
title: const Text('Tampilkan Terjemahan'),
|
|
value: _showTerjemahan,
|
|
activeColor: AppColors.primary,
|
|
onChanged: (val) {
|
|
setModalState(() => _showTerjemahan = val);
|
|
setState(() => _showTerjemahan = val);
|
|
final box = Hive.box<AppSettings>(HiveBoxes.settings);
|
|
final settings = box.get('default') ?? AppSettings();
|
|
settings.showTerjemahan = val;
|
|
settings.save();
|
|
},
|
|
),
|
|
const SizedBox(height: 16),
|
|
],
|
|
),
|
|
);
|
|
},
|
|
),
|
|
);
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
final isDark = Theme.of(context).brightness == Brightness.dark;
|
|
final filtered = _searchQuery.isEmpty
|
|
? _surahs
|
|
: _surahs
|
|
.where((s) =>
|
|
(s['namaLatin'] as String? ?? '')
|
|
.toLowerCase()
|
|
.contains(_searchQuery.toLowerCase()) ||
|
|
(s['nama'] as String? ?? '').contains(_searchQuery))
|
|
.toList();
|
|
|
|
return Scaffold(
|
|
appBar: AppBar(
|
|
automaticallyImplyLeading: !widget.isSimpleModeTab,
|
|
title: const Text('Al-Quran'),
|
|
actions: [
|
|
IconButton(
|
|
icon: const Icon(LucideIcons.bookmark),
|
|
onPressed: () => context.push(widget.isSimpleModeTab
|
|
? '/quran/bookmarks'
|
|
: '/tools/quran/bookmarks'),
|
|
),
|
|
IconButton(
|
|
icon: const Icon(LucideIcons.sparkles),
|
|
onPressed: () => context.push(widget.isSimpleModeTab
|
|
? '/quran/enrichment'
|
|
: '/tools/quran/enrichment'),
|
|
),
|
|
IconButton(
|
|
icon: const Icon(LucideIcons.settings2),
|
|
onPressed: _showDisplaySettings,
|
|
),
|
|
],
|
|
),
|
|
body: SafeArea(
|
|
top: false,
|
|
bottom: !widget.isSimpleModeTab,
|
|
child: Column(
|
|
children: [
|
|
// Search bar
|
|
Padding(
|
|
padding: const EdgeInsets.fromLTRB(16, 8, 16, 12),
|
|
child: Container(
|
|
decoration: BoxDecoration(
|
|
color:
|
|
isDark ? AppColors.surfaceDark : AppColors.surfaceLight,
|
|
borderRadius: BorderRadius.circular(12),
|
|
border: Border.all(
|
|
color: isDark
|
|
? AppColors.primary.withValues(alpha: 0.1)
|
|
: AppColors.cream,
|
|
),
|
|
),
|
|
child: TextField(
|
|
onChanged: (v) => setState(() => _searchQuery = v),
|
|
decoration: InputDecoration(
|
|
hintText: 'Cari surah...',
|
|
prefixIcon: Icon(LucideIcons.search,
|
|
color: isDark
|
|
? AppColors.textSecondaryDark
|
|
: AppColors.textSecondaryLight),
|
|
border: InputBorder.none,
|
|
contentPadding: const EdgeInsets.symmetric(
|
|
horizontal: 16, vertical: 14),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
// Surah list
|
|
Expanded(
|
|
child: _loading
|
|
? const Center(child: CircularProgressIndicator())
|
|
: filtered.isEmpty
|
|
? Center(
|
|
child: Text(
|
|
_searchQuery.isEmpty
|
|
? 'Tidak dapat memuat data'
|
|
: 'Surah tidak ditemukan',
|
|
style: TextStyle(
|
|
color: isDark
|
|
? AppColors.textSecondaryDark
|
|
: AppColors.textSecondaryLight,
|
|
),
|
|
),
|
|
)
|
|
: ValueListenableBuilder(
|
|
valueListenable:
|
|
Hive.box<QuranBookmark>(HiveBoxes.bookmarks)
|
|
.listenable(),
|
|
builder: (context, box, _) {
|
|
return ListView.separated(
|
|
padding:
|
|
const EdgeInsets.symmetric(horizontal: 16),
|
|
itemCount: filtered.length,
|
|
separatorBuilder: (_, __) => Divider(
|
|
height: 1,
|
|
color: isDark
|
|
? AppColors.primary.withValues(alpha: 0.08)
|
|
: AppColors.cream,
|
|
),
|
|
itemBuilder: (context, i) {
|
|
final surah = filtered[i];
|
|
final number = surah['nomor'] ?? (i + 1);
|
|
final nameLatin = surah['namaLatin'] ?? '';
|
|
final nameArabic = surah['nama'] ?? '';
|
|
final totalVerses = surah['jumlahAyat'] ?? 0;
|
|
final tempatTurun = surah['tempatTurun'] ?? '';
|
|
final arti = surah['arti'] ?? '';
|
|
|
|
final hasLastRead = box.values.any(
|
|
(b) => b.isLastRead && b.surahId == number);
|
|
|
|
return ListTile(
|
|
onTap: () => context.push(
|
|
widget.isSimpleModeTab
|
|
? '/quran/$number'
|
|
: '/tools/quran/$number'),
|
|
contentPadding: const EdgeInsets.symmetric(
|
|
horizontal: 0, vertical: 6),
|
|
leading: Container(
|
|
width: 40,
|
|
height: 40,
|
|
decoration: BoxDecoration(
|
|
color: AppColors.primary
|
|
.withValues(alpha: 0.1),
|
|
borderRadius: BorderRadius.circular(10),
|
|
),
|
|
child: Center(
|
|
child: Text(
|
|
'$number',
|
|
style: TextStyle(
|
|
fontSize: 14,
|
|
fontWeight: FontWeight.w700,
|
|
color: AppColors.primary,
|
|
),
|
|
),
|
|
),
|
|
),
|
|
title: Row(
|
|
children: [
|
|
Text(
|
|
nameLatin,
|
|
style: const TextStyle(
|
|
fontWeight: FontWeight.w600,
|
|
fontSize: 15,
|
|
),
|
|
),
|
|
if (hasLastRead) ...[
|
|
const SizedBox(width: 8),
|
|
const Icon(LucideIcons.pin,
|
|
size: 14, color: AppColors.primary),
|
|
],
|
|
],
|
|
),
|
|
subtitle: Text(
|
|
'$arti • $totalVerses Ayat • $tempatTurun',
|
|
style: TextStyle(
|
|
fontSize: 12,
|
|
color: isDark
|
|
? AppColors.textSecondaryDark
|
|
: AppColors.textSecondaryLight,
|
|
),
|
|
),
|
|
trailing: ArabicText(
|
|
nameArabic,
|
|
baseFontSize: 18,
|
|
fontWeight: FontWeight.w400,
|
|
),
|
|
);
|
|
},
|
|
);
|
|
},
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|