Implement dynamic scripture loading from XML and fix theming for Learn screens
This commit is contained in:
@@ -19,7 +19,7 @@ class _HusbandLearnScreen extends StatelessWidget {
|
|||||||
style: GoogleFonts.outfit(
|
style: GoogleFonts.outfit(
|
||||||
fontSize: 28,
|
fontSize: 28,
|
||||||
fontWeight: FontWeight.w600,
|
fontWeight: FontWeight.w600,
|
||||||
color: AppColors.navyBlue,
|
color: Theme.of(context).textTheme.displayMedium?.color,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 24),
|
const SizedBox(height: 24),
|
||||||
@@ -94,14 +94,14 @@ class _HusbandLearnScreen extends StatelessWidget {
|
|||||||
style: GoogleFonts.outfit(
|
style: GoogleFonts.outfit(
|
||||||
fontSize: 14,
|
fontSize: 14,
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
color: AppColors.warmGray,
|
color: Theme.of(context).textTheme.bodySmall?.color,
|
||||||
letterSpacing: 0.5,
|
letterSpacing: 0.5,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 8),
|
const SizedBox(height: 8),
|
||||||
Container(
|
Container(
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: Colors.white,
|
color: Theme.of(context).cardTheme.color,
|
||||||
borderRadius: BorderRadius.circular(12),
|
borderRadius: BorderRadius.circular(12),
|
||||||
),
|
),
|
||||||
child: Column(
|
child: Column(
|
||||||
@@ -111,12 +111,12 @@ class _HusbandLearnScreen extends StatelessWidget {
|
|||||||
width: 40,
|
width: 40,
|
||||||
height: 40,
|
height: 40,
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: AppColors.navyBlue.withOpacity(0.1),
|
color: Theme.of(context).colorScheme.primary.withOpacity(0.1),
|
||||||
borderRadius: BorderRadius.circular(10),
|
borderRadius: BorderRadius.circular(10),
|
||||||
),
|
),
|
||||||
child: Icon(
|
child: Icon(
|
||||||
item.icon,
|
item.icon,
|
||||||
color: AppColors.navyBlue,
|
color: Theme.of(context).colorScheme.primary,
|
||||||
size: 20,
|
size: 20,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -125,19 +125,19 @@ class _HusbandLearnScreen extends StatelessWidget {
|
|||||||
style: GoogleFonts.outfit(
|
style: GoogleFonts.outfit(
|
||||||
fontSize: 15,
|
fontSize: 15,
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
color: AppColors.charcoal,
|
color: Theme.of(context).textTheme.bodyLarge?.color,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
subtitle: Text(
|
subtitle: Text(
|
||||||
item.subtitle,
|
item.subtitle,
|
||||||
style: GoogleFonts.outfit(
|
style: GoogleFonts.outfit(
|
||||||
fontSize: 13,
|
fontSize: 13,
|
||||||
color: AppColors.warmGray,
|
color: Theme.of(context).textTheme.bodyMedium?.color,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
trailing: const Icon(
|
trailing: Icon(
|
||||||
Icons.chevron_right,
|
Icons.chevron_right,
|
||||||
color: AppColors.lightGray,
|
color: Theme.of(context).disabledColor,
|
||||||
),
|
),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
Navigator.push(
|
Navigator.push(
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import '../../models/user_profile.dart';
|
|||||||
import '../../models/teaching_plan.dart';
|
import '../../models/teaching_plan.dart';
|
||||||
import '../../providers/user_provider.dart';
|
import '../../providers/user_provider.dart';
|
||||||
import '../../theme/app_theme.dart';
|
import '../../theme/app_theme.dart';
|
||||||
|
import '../../services/bible_xml_parser.dart';
|
||||||
|
|
||||||
class HusbandDevotionalScreen extends ConsumerStatefulWidget {
|
class HusbandDevotionalScreen extends ConsumerStatefulWidget {
|
||||||
const HusbandDevotionalScreen({super.key});
|
const HusbandDevotionalScreen({super.key});
|
||||||
@@ -15,6 +16,61 @@ class HusbandDevotionalScreen extends ConsumerStatefulWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _HusbandDevotionalScreenState extends ConsumerState<HusbandDevotionalScreen> {
|
class _HusbandDevotionalScreenState extends ConsumerState<HusbandDevotionalScreen> {
|
||||||
|
final _parser = BibleXmlParser();
|
||||||
|
Map<String, String> _scriptures = {};
|
||||||
|
bool _loading = true;
|
||||||
|
BibleTranslation? _currentTranslation;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
// Initial fetch handled in post-frame or via listen, but let's trigger once here if possible
|
||||||
|
// We need the ref, which is available.
|
||||||
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||||
|
_fetchScriptures();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _fetchScriptures() async {
|
||||||
|
final user = ref.read(userProfileProvider);
|
||||||
|
if (user == null) return;
|
||||||
|
|
||||||
|
final translation = user.bibleTranslation;
|
||||||
|
if (translation == _currentTranslation && _scriptures.isNotEmpty) return;
|
||||||
|
|
||||||
|
setState(() => _loading = true);
|
||||||
|
|
||||||
|
try {
|
||||||
|
final assetPath = 'assets/bible_xml/${translation.name.toUpperCase()}.xml';
|
||||||
|
|
||||||
|
// Define verses to fetch
|
||||||
|
final versesToFetch = [
|
||||||
|
'1 Corinthians 11:3',
|
||||||
|
'1 Timothy 3:4',
|
||||||
|
'1 Timothy 3:5',
|
||||||
|
'1 Timothy 3:12',
|
||||||
|
'Titus 1:6',
|
||||||
|
];
|
||||||
|
|
||||||
|
final Map<String, String> results = {};
|
||||||
|
|
||||||
|
for (final ref in versesToFetch) {
|
||||||
|
final text = await _parser.getVerseFromAsset(assetPath, ref);
|
||||||
|
results[ref] = text ?? 'Verse not found.';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mounted) {
|
||||||
|
setState(() {
|
||||||
|
_scriptures = results;
|
||||||
|
_currentTranslation = translation;
|
||||||
|
_loading = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
debugPrint('Error loading scriptures: $e');
|
||||||
|
if (mounted) setState(() => _loading = false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void _showAddTeachingDialog([TeachingPlan? existingPlan]) {
|
void _showAddTeachingDialog([TeachingPlan? existingPlan]) {
|
||||||
final titleController = TextEditingController(text: existingPlan?.topic);
|
final titleController = TextEditingController(text: existingPlan?.topic);
|
||||||
@@ -163,6 +219,13 @@ class _HusbandDevotionalScreenState extends ConsumerState<HusbandDevotionalScree
|
|||||||
final upcomingPlans = user?.teachingPlans ?? [];
|
final upcomingPlans = user?.teachingPlans ?? [];
|
||||||
upcomingPlans.sort((a,b) => a.date.compareTo(b.date));
|
upcomingPlans.sort((a,b) => a.date.compareTo(b.date));
|
||||||
|
|
||||||
|
// Listen for translation changes to re-fetch
|
||||||
|
ref.listen(userProfileProvider, (prev, next) {
|
||||||
|
if (next?.bibleTranslation != prev?.bibleTranslation) {
|
||||||
|
_fetchScriptures();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: const Text('Spiritual Leadership'),
|
title: const Text('Spiritual Leadership'),
|
||||||
@@ -174,7 +237,7 @@ class _HusbandDevotionalScreenState extends ConsumerState<HusbandDevotionalScree
|
|||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
// Informational Card (Headship)
|
// Informational Card (Headship)
|
||||||
_buildHeadshipCard(),
|
_buildHeadshipCard(user?.bibleTranslation.label ?? 'ESV'),
|
||||||
const SizedBox(height: 24),
|
const SizedBox(height: 24),
|
||||||
|
|
||||||
Row(
|
Row(
|
||||||
@@ -289,7 +352,15 @@ class _HusbandDevotionalScreenState extends ConsumerState<HusbandDevotionalScree
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildHeadshipCard() {
|
Widget _buildHeadshipCard(String version) {
|
||||||
|
// Combine 1 Timothy verses
|
||||||
|
String timothyText = 'Loading...';
|
||||||
|
if (!_loading) {
|
||||||
|
timothyText = '${_scriptures['1 Timothy 3:4'] ?? '...'} ${_scriptures['1 Timothy 3:5'] ?? ''} ... ${_scriptures['1 Timothy 3:12'] ?? ''}';
|
||||||
|
// Cleanup potential double spaces or missing
|
||||||
|
timothyText = timothyText.replaceAll(' ', ' ').trim();
|
||||||
|
}
|
||||||
|
|
||||||
return Container(
|
return Container(
|
||||||
padding: const EdgeInsets.all(20),
|
padding: const EdgeInsets.all(20),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
@@ -304,6 +375,9 @@ class _HusbandDevotionalScreenState extends ConsumerState<HusbandDevotionalScree
|
|||||||
children: [
|
children: [
|
||||||
const Icon(Icons.menu_book, color: Color(0xFF8B5E3C)),
|
const Icon(Icons.menu_book, color: Color(0xFF8B5E3C)),
|
||||||
const SizedBox(width: 12),
|
const SizedBox(width: 12),
|
||||||
|
Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
Text(
|
Text(
|
||||||
'Biblical Principles',
|
'Biblical Principles',
|
||||||
style: GoogleFonts.lora(
|
style: GoogleFonts.lora(
|
||||||
@@ -312,20 +386,32 @@ class _HusbandDevotionalScreenState extends ConsumerState<HusbandDevotionalScree
|
|||||||
color: const Color(0xFF5D4037),
|
color: const Color(0xFF5D4037),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
Text(
|
||||||
|
version,
|
||||||
|
style: GoogleFonts.outfit(fontSize: 12, color: const Color(0xFF8B5E3C)),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
const SizedBox(height: 16),
|
const SizedBox(height: 16),
|
||||||
_buildVerseText(
|
_buildVerseText(
|
||||||
'1 Corinthians 11:3',
|
'1 Corinthians 11:3',
|
||||||
'“The head of every man is Christ, the head of a wife is her husband, and the head of Christ is God.”',
|
_loading ? 'Loading...' : (_scriptures['1 Corinthians 11:3'] ?? 'Verse not found.'),
|
||||||
'Supports family structure under Christ’s authority.',
|
'Supports family structure under Christ’s authority.',
|
||||||
),
|
),
|
||||||
const SizedBox(height: 16),
|
const SizedBox(height: 16),
|
||||||
const Divider(height: 1, color: Color(0xFFE0C097)),
|
const Divider(height: 1, color: Color(0xFFE0C097)),
|
||||||
const SizedBox(height: 16),
|
const SizedBox(height: 16),
|
||||||
_buildVerseText(
|
_buildVerseText(
|
||||||
'1 Tim 3:4–5, 12 & Titus 1:6',
|
'1 Timothy 3:4–5, 12',
|
||||||
|
timothyText,
|
||||||
'Qualifications for church elders include managing their own households well.',
|
'Qualifications for church elders include managing their own households well.',
|
||||||
|
),
|
||||||
|
const SizedBox(height: 16),
|
||||||
|
_buildVerseText(
|
||||||
|
'Titus 1:6',
|
||||||
|
_loading ? 'Loading...' : (_scriptures['Titus 1:6'] ?? 'Verse not found.'),
|
||||||
'Husbands who lead faithfully at home are seen as candidates for formal spiritual leadership.',
|
'Husbands who lead faithfully at home are seen as candidates for formal spiritual leadership.',
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@@ -346,8 +432,11 @@ class _HusbandDevotionalScreenState extends ConsumerState<HusbandDevotionalScree
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 4),
|
const SizedBox(height: 4),
|
||||||
Text(
|
AnimatedSwitcher(
|
||||||
|
duration: const Duration(milliseconds: 300),
|
||||||
|
child: Text(
|
||||||
text,
|
text,
|
||||||
|
key: ValueKey(text), // Animate change
|
||||||
style: GoogleFonts.lora(
|
style: GoogleFonts.lora(
|
||||||
fontSize: 15,
|
fontSize: 15,
|
||||||
fontStyle: FontStyle.italic,
|
fontStyle: FontStyle.italic,
|
||||||
@@ -355,6 +444,7 @@ class _HusbandDevotionalScreenState extends ConsumerState<HusbandDevotionalScree
|
|||||||
color: const Color(0xFF3E2723),
|
color: const Color(0xFF3E2723),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
),
|
||||||
const SizedBox(height: 4),
|
const SizedBox(height: 4),
|
||||||
Text(
|
Text(
|
||||||
context,
|
context,
|
||||||
|
|||||||
Reference in New Issue
Block a user