feat: Implement husband features and fix iOS Safari web startup

Implement initial features for husband's companion app, including mock data
service and husband notes screen. Refactor scripture and cycle services
for improved stability and testability. Address iOS Safari web app
startup issue by removing deprecated initialization.

- Implemented MockDataService and HusbandNotesScreen.
- Converted _DashboardTab and DevotionalScreen to StatefulWidgets for robust
  scripture provider initialization.
- Refactored CycleService to use immutable CycleInfo class, reducing UI rebuilds.
- Removed deprecated window.flutterConfiguration from index.html, resolving
  Flutter web app startup failure on iOS Safari.
- Updated and fixed related tests.
This commit is contained in:
2025-12-26 22:40:52 -06:00
parent 464692ce56
commit b4b2bfe749
47 changed files with 240110 additions and 2578 deletions

View File

@@ -1,469 +1,541 @@
<<<<<<< HEAD
/// Scripture model for daily verses and devotionals
class Scripture {
final String verse;
=======
import 'dart:convert';
import 'dart:math';
import 'package:flutter/services.dart';
import 'package:hive_flutter/hive_flutter.dart'; // Import Hive
import '../services/bible_xml_parser.dart'; // Import the XML parser
import 'cycle_entry.dart';
import 'user_profile.dart';
part 'scripture.g.dart'; // Hive generated adapter
/// Scripture model for daily verses and devotionals
class Scripture {
@HiveType(typeId: 10) // Unique typeId for Scripture
class Scripture extends HiveObject {
@HiveField(0)
final Map<BibleTranslation, String> verses;
>>>>>>> 6742220 (Your commit message here)
@HiveField(1)
final String reference;
@HiveField(2)
final String? reflection;
@HiveField(3)
final List<String> applicablePhases;
@HiveField(4)
final List<String> applicableContexts;
const Scripture({
<<<<<<< HEAD
required this.verse,
=======
Scripture({
required this.verses,
>>>>>>> 6742220 (Your commit message here)
required this.reference,
this.reflection,
this.applicablePhases = const [],
this.applicableContexts = const [],
});
<<<<<<< HEAD
=======
factory Scripture.fromJson(Map<String, dynamic> json) {
return Scripture(
verses: (json['verses'] as Map<String, dynamic>).map((key, value) =>
MapEntry(
BibleTranslation.values.firstWhere((e) => e.name == key), value)),
reference: json['reference'],
reflection: json['reflection'],
applicablePhases: (json['applicablePhases'] as List<dynamic>?)
?.map((e) => e as String)
.toList() ??
[],
applicableContexts: (json['applicableContexts'] as List<dynamic>?)
?.map((e) => e as String)
.toList() ??
[],
);
}
String getVerse(BibleTranslation translation) {
return verses[translation] ?? verses[BibleTranslation.esv] ?? verses.values.first;
return verses[translation] ??
verses[BibleTranslation.esv] ??
verses.values.first;
}
@override
bool operator ==(Object other) =>
identical(this, other) ||
(other is Scripture &&
runtimeType == other.runtimeType &&
reference == other.reference &&
reflection == other.reflection &&
_listEquals(applicablePhases, other.applicablePhases) &&
_listEquals(applicableContexts, other.applicableContexts) &&
_mapEquals(verses, other.verses));
@override
int get hashCode =>
reference.hashCode ^
reflection.hashCode ^
Object.hashAll(applicablePhases) ^
Object.hashAll(applicableContexts) ^
Object.hashAll(verses.entries) ^
reflection.hashCode;
// Helper for list equality check
static bool _listEquals<T>(List<T>? a, List<T>? b) {
if (a == null) return b == null;
if (b == null) return false;
if (a.length != b.length) return false;
for (int i = 0; i < a.length; i++) {
if (a[i] != b[i]) return false;
}
return true;
}
// Helper for map equality check
static bool _mapEquals<K, V>(Map<K, V>? a, Map<K, V>? b) {
if (a == null) return b == null;
if (b == null) return false;
if (a.length != b.length) return false;
if (a.keys.length != b.keys.length) return false; // Added length check
for (final key in a.keys) {
if (!b.containsKey(key) || a[key] != b[key]) return false; // Added containsKey check
}
return true;
}
>>>>>>> 6742220 (Your commit message here)
}
/// Pre-defined scriptures for the app
class ScriptureDatabase {
/// Scriptures for menstrual phase (rest, comfort)
static const List<Scripture> menstrualScriptures = [
Scripture(
<<<<<<< HEAD
verse: "Come to me, all you who are weary and burdened, and I will give you rest.",
=======
verses: {
BibleTranslation.esv: "Come to me, all who labor and are heavy laden, and I will give you rest.",
BibleTranslation.niv: "Come to me, all you who are weary and burdened, and I will give you rest.",
BibleTranslation.nkjv: "Come to me, all you who labor and are heavy laden, and I will give you rest.",
BibleTranslation.nlt: "Come to me, all of you who are weary and carry heavy burdens, and I will give you rest.",
BibleTranslation.nasb: "Come to Me, all who are weary and burdened, and I will give you rest.",
BibleTranslation.kjv: "Come unto me, all ye that labour and are heavy laden, and I will give you rest.",
},
>>>>>>> 6742220 (Your commit message here)
reference: "Matthew 11:28",
reflection: "Your body is doing important work. Rest is not weakness—it's wisdom.",
applicablePhases: ['menstrual'],
),
Scripture(
<<<<<<< HEAD
verse: "He gives strength to the weary and increases the power of the weak.",
=======
verses: {
BibleTranslation.esv: "He gives power to the faint, and to him who has no might he increases strength.",
BibleTranslation.niv: "He gives strength to the weary and increases the power of the weak.",
BibleTranslation.nkjv: "He gives power to the weak, and to those who have no might He increases strength.",
BibleTranslation.nasb: "He gives strength to the weary, and to the one who lacks might He increases power.",
},
>>>>>>> 6742220 (Your commit message here)
reference: "Isaiah 40:29",
applicablePhases: ['menstrual'],
),
Scripture(
<<<<<<< HEAD
verse: "The Lord is my shepherd; I shall not want. He makes me lie down in green pastures.",
reference: "Psalm 23:1-2",
applicablePhases: ['menstrual'],
),
Scripture(
verse: "Be still, and know that I am God.",
reference: "Psalm 46:10",
reflection: "Use this time of slowing down to be present with God.",
applicablePhases: ['menstrual'],
),
Scripture(
verse: "My grace is sufficient for you, for my power is made perfect in weakness.",
reference: "2 Corinthians 12:9",
applicablePhases: ['menstrual'],
),
=======
verses: {
BibleTranslation.esv: "The LORD is my shepherd; I shall not want. He makes me lie down in green pastures.",
BibleTranslation.niv: "The LORD is my shepherd, I lack nothing. He makes me lie down in green pastures.",
BibleTranslation.nkjv: "The LORD is my shepherd; I shall not want. He makes me to lie down in green pastures.",
},
reference: "Psalm 23:1-2",
applicablePhases: ['menstrual'],
),
>>>>>>> 6742220 (Your commit message here)
];
/// Scriptures for follicular phase (renewal, strength)
static const List<Scripture> follicularScriptures = [
Scripture(
<<<<<<< HEAD
verse: "She is clothed with strength and dignity; she can laugh at the days to come.",
=======
verses: {
BibleTranslation.esv: "Strength and dignity are her clothing, and she laughs at the time to come.",
BibleTranslation.niv: "She is clothed with strength and dignity; she can laugh at the days to come.",
BibleTranslation.nkjv: "Strength and honor are her clothing; she shall rejoice in time to come.",
BibleTranslation.nlt: "She is clothed with strength and dignity, and she laughs without fear of the future.",
},
>>>>>>> 6742220 (Your commit message here)
reference: "Proverbs 31:25",
reflection: "You're entering a season of renewed energy. Use it for His glory.",
applicablePhases: ['follicular'],
),
Scripture(
<<<<<<< HEAD
verse: "I can do all this through him who gives me strength.",
=======
verses: {
BibleTranslation.esv: "I can do all things through him who strengthens me.",
BibleTranslation.niv: "I can do all this through him who gives me strength.",
BibleTranslation.nkjv: "I can do all things through Christ who strengthens me.",
},
>>>>>>> 6742220 (Your commit message here)
reference: "Philippians 4:13",
applicablePhases: ['follicular'],
),
Scripture(
<<<<<<< HEAD
verse: "But those who hope in the Lord will renew their strength. They will soar on wings like eagles.",
reference: "Isaiah 40:31",
applicablePhases: ['follicular'],
),
Scripture(
verse: "This is the day the Lord has made; let us rejoice and be glad in it.",
reference: "Psalm 118:24",
applicablePhases: ['follicular'],
),
Scripture(
verse: "The Lord your God is with you, the Mighty Warrior who saves.",
reference: "Zephaniah 3:17",
applicablePhases: ['follicular'],
),
=======
verses: {
BibleTranslation.esv: "but they who wait for the LORD shall renew their strength; they shall mount up with wings like eagles.",
BibleTranslation.niv: "but those who hope in the LORD will renew their strength. They will soar on wings like eagles.",
},
reference: "Isaiah 40:31",
applicablePhases: ['follicular'],
),
>>>>>>> 6742220 (Your commit message here)
];
/// Scriptures for ovulation phase (creation, beauty)
static const List<Scripture> ovulationScriptures = [
Scripture(
<<<<<<< HEAD
verse: "For you created my inmost being; you knit me together in my mother's womb. I praise you because I am fearfully and wonderfully made.",
=======
verses: {
BibleTranslation.esv: "For you formed my inmost parts; you knitted me together in my mother's womb. I praise you, for I am fearfully and wonderfully made.",
BibleTranslation.niv: "For you created my inmost being; you knit me together in my mothers womb. I praise you because I am fearfully and wonderfully made.",
BibleTranslation.nkjv: "For You formed my inward parts; You covered me in my mothers womb. I will praise You, for I am fearfully and wonderfully made.",
},
>>>>>>> 6742220 (Your commit message here)
reference: "Psalm 139:13-14",
reflection: "Your body reflects the incredible creativity of God.",
applicablePhases: ['ovulation'],
),
Scripture(
<<<<<<< HEAD
verse: "Children are a heritage from the Lord, offspring a reward from him.",
reference: "Psalm 127:3",
applicablePhases: ['ovulation'],
),
Scripture(
verse: "See, I am doing a new thing! Now it springs up; do you not perceive it?",
reference: "Isaiah 43:19",
applicablePhases: ['ovulation'],
),
Scripture(
verse: "Every good and perfect gift is from above.",
reference: "James 1:17",
applicablePhases: ['ovulation'],
),
=======
verses: {
BibleTranslation.esv: "Behold, children are a heritage from the LORD, the fruit of the womb a reward.",
BibleTranslation.niv: "Children are a heritage from the LORD, offspring a reward from him.",
BibleTranslation.nkjv: "Behold, children are a heritage from the LORD, the fruit of the womb is a reward.",
},
reference: "Psalm 127:3",
applicablePhases: ['ovulation'],
),
>>>>>>> 6742220 (Your commit message here)
];
/// Scriptures for luteal phase / TWW (patience, trust)
static const List<Scripture> lutealScriptures = [
Scripture(
<<<<<<< HEAD
verse: "For I know the plans I have for you, declares the Lord, plans to prosper you and not to harm you, plans to give you hope and a future.",
=======
verses: {
BibleTranslation.esv: "For I know the plans I have for you, declares the LORD, plans for welfare and not for evil, to give you a future and a hope.",
BibleTranslation.niv: "For I know the plans I have for you,” declares the LORD, “plans to prosper you and not to harm you, plans to give you hope and a future.",
BibleTranslation.nkjv: "For I know the thoughts that I think toward you, says the LORD, thoughts of peace and not of evil, to give you a future and a hope.",
},
>>>>>>> 6742220 (Your commit message here)
reference: "Jeremiah 29:11",
reflection: "Whatever this season holds, God's plans for you are good.",
applicablePhases: ['luteal'],
),
Scripture(
<<<<<<< HEAD
verse: "Do not be anxious about anything, but in every situation, by prayer and petition, with thanksgiving, present your requests to God.",
=======
verses: {
BibleTranslation.esv: "do not be anxious about anything, but in everything by prayer and supplication with thanksgiving let your requests be made known to God.",
BibleTranslation.niv: "Do not be anxious about anything, but in every situation, by prayer and petition, with thanksgiving, present your requests to God.",
},
>>>>>>> 6742220 (Your commit message here)
reference: "Philippians 4:6",
applicablePhases: ['luteal'],
),
Scripture(
<<<<<<< HEAD
verse: "Trust in the Lord with all your heart and lean not on your own understanding.",
reference: "Proverbs 3:5",
applicablePhases: ['luteal'],
),
Scripture(
verse: "The Lord is close to the brokenhearted and saves those who are crushed in spirit.",
reference: "Psalm 34:18",
applicablePhases: ['luteal'],
),
Scripture(
verse: "And the peace of God, which transcends all understanding, will guard your hearts and your minds in Christ Jesus.",
reference: "Philippians 4:7",
applicablePhases: ['luteal'],
),
Scripture(
verse: "Wait for the Lord; be strong and take heart and wait for the Lord.",
reference: "Psalm 27:14",
applicablePhases: ['luteal'],
),
=======
verses: {
BibleTranslation.esv: "Trust in the LORD with all your heart, and do not lean on your own understanding.",
BibleTranslation.niv: "Trust in the LORD with all your heart and lean not on your own understanding.",
},
reference: "Proverbs 3:5",
applicablePhases: ['luteal'],
),
>>>>>>> 6742220 (Your commit message here)
];
/// Scriptures for husbands
static const List<Scripture> husbandScriptures = [
Scripture(
<<<<<<< HEAD
verse: "Husbands, love your wives, just as Christ loved the church and gave himself up for her.",
=======
verses: {
BibleTranslation.esv: "Husbands, love your wives, as Christ loved the church and gave himself up for her.",
BibleTranslation.niv: "Husbands, love your wives, just as Christ loved the church and gave himself up for her.",
},
>>>>>>> 6742220 (Your commit message here)
reference: "Ephesians 5:25",
reflection: "Love sacrificially—putting her needs before your own.",
),
Scripture(
<<<<<<< HEAD
verse: "Husbands, in the same way be considerate as you live with your wives, and treat them with respect.",
reference: "1 Peter 3:7",
),
Scripture(
verse: "Two are better than one, because they have a good return for their labor.",
reference: "Ecclesiastes 4:9",
),
Scripture(
verse: "Be completely humble and gentle; be patient, bearing with one another in love.",
reference: "Ephesians 4:2",
),
Scripture(
verse: "Above all, love each other deeply, because love covers over a multitude of sins.",
reference: "1 Peter 4:8",
),
Scripture(
verse: "A husband should fulfill his duty to his wife.",
reference: "1 Corinthians 7:3",
),
Scripture(
verse: "He who finds a wife finds what is good and receives favor from the Lord.",
reference: "Proverbs 18:22",
),
=======
verses: {
BibleTranslation.esv: "Likewise, husbands, live with your wives in an understanding way, showing honor to the woman.",
BibleTranslation.niv: "Husbands, in the same way be considerate as you live with your wives, and treat them with respect.",
},
reference: "1 Peter 3:7",
),
>>>>>>> 6742220 (Your commit message here)
];
/// General womanhood scriptures
static const List<Scripture> womanhoodScriptures = [
Scripture(
<<<<<<< HEAD
verse: "Charm is deceptive, and beauty is fleeting; but a woman who fears the Lord is to be praised.",
reference: "Proverbs 31:30",
),
Scripture(
verse: "She opens her mouth with wisdom, and the teaching of kindness is on her tongue.",
reference: "Proverbs 31:26",
),
Scripture(
verse: "Your beauty should not come from outward adornment... Rather, it should be that of your inner self, the unfading beauty of a gentle and quiet spirit.",
reference: "1 Peter 3:3-4",
),
Scripture(
verse: "God is within her, she will not fall; God will help her at break of day.",
reference: "Psalm 46:5",
),
];
=======
verses: {
BibleTranslation.esv: "Charm is deceitful, and beauty is vain, but a woman who fears the LORD is to be praised.",
BibleTranslation.niv: "Charm is deceptive, and beauty is fleeting; but a woman who fears the LORD is to be praised.",
},
reference: "Proverbs 31:30",
),
Scripture(
verses: {
BibleTranslation.esv: "She opens her mouth with wisdom, and the teaching of kindness is on her tongue.",
BibleTranslation.niv: "She opens her mouth with wisdom, and the teaching of kindness is on her tongue.",
},
reference: "Proverbs 31:26",
),
];
/// Scriptures for specific needs (contextual)
static const Map<String, List<Scripture>> contextualScriptures = {
'pain': [
Scripture(
verses: {
BibleTranslation.esv: "The LORD is near to the brokenhearted and saves the crushed in spirit.",
BibleTranslation.niv: "The LORD is close to the brokenhearted and saves those who are crushed in spirit.",
},
reference: "Psalm 34:18",
reflection: "He sees your pain and draws near to you in your discomfort.",
),
Scripture(
verses: {
BibleTranslation.esv: "Cast your burden on the LORD, and he will sustain you.",
BibleTranslation.niv: "Cast your cares on the LORD and he will sustain you.",
},
reference: "Psalm 55:22",
),
],
'fatigue': [
Scripture(
verses: {
BibleTranslation.esv: "He gives power to the faint, and to him who has no might he increases strength.",
BibleTranslation.niv: "He gives strength to the weary and increases the power of the weak.",
},
reference: "Isaiah 40:29",
),
Scripture(
verses: {
BibleTranslation.esv: "My grace is sufficient for you, for my power is made perfect in weakness.",
BibleTranslation.niv: "My grace is sufficient for you, for my power is made perfect in weakness.",
},
reference: "2 Corinthians 12:9",
),
],
'anxiety': [
Scripture(
verses: {
BibleTranslation.esv: "When the cares of my heart are many, your consolations cheer my soul.",
BibleTranslation.niv: "When anxiety was great within me, your consolation brought me joy.",
},
reference: "Psalm 94:19",
),
Scripture(
verses: {
BibleTranslation.esv: "Peace I leave with you; my peace I give to you. Not as the world gives do I give to you. Let not your hearts be troubled, neither let them be afraid.",
BibleTranslation.niv: "Peace I leave with you; my peace I give to you. I do not give to you as the world gives. Do not let your hearts be troubled and do not be afraid.",
},
reference: "John 14:27",
),
],
'joy': [
Scripture(
verses: {
BibleTranslation.esv: "The LORD is my strength and my shield; in him my heart trusts, and I am helped; my heart exults, and with my song I give thanks to him.",
BibleTranslation.niv: "The LORD is my strength and my shield; my heart trusts in him, and he helps me. My heart leaps for joy, and with my song I praise him.",
},
reference: "Psalm 28:7",
),
],
static final ScriptureDatabase _instance = ScriptureDatabase._internal();
factory ScriptureDatabase({BibleXmlParser? bibleXmlParser}) {
_instance._bibleXmlParser = bibleXmlParser ?? BibleXmlParser();
return _instance;
}
ScriptureDatabase._internal();
late BibleXmlParser _bibleXmlParser;
late Box<Scripture> _scriptureBox;
// Mapping of BibleTranslation to its XML asset path
final Map<BibleTranslation, String> _translationFileMapping = {
BibleTranslation.esv: 'bible_xml/ESV.xml',
BibleTranslation.niv: 'bible_xml/NIV.xml',
BibleTranslation.nkjv: 'bible_xml/NKJV.xml',
BibleTranslation.nlt: 'bible_xml/NLT.xml',
BibleTranslation.nasb: 'bible_xml/NASB.xml',
BibleTranslation.kjv: 'bible_xml/KJV.xml',
BibleTranslation.msg: 'bible_xml/MSG.xml',
};
List<Scripture> _menstrualScriptures = [];
List<Scripture> _follicularScriptures = [];
List<Scripture> _ovulationScriptures = [];
List<Scripture> _lutealScriptures = [];
List<Scripture> _husbandScriptures = [];
List<Scripture> _womanhoodScriptures = [];
Map<String, List<Scripture>> _contextualScriptures = {};
// Hardcoded scriptures to ensure rich Husband experience immediately
final List<Scripture> _hardcodedHusbandScriptures = [
Scripture(
reference: "Mark 10:45",
verses: {
BibleTranslation.esv: "For even the Son of Man came not to be served but to serve, and to give his life as a ransom for many.",
BibleTranslation.niv: "For even the Son of Man did not come to be served, but to serve, and to give his life as a ransom for many.",
},
reflection: "True leadership is servanthood. How can you serve your wife today?",
applicablePhases: ['husband'],
applicableContexts: ['leadership', 'servant'],
),
Scripture(
reference: "Philippians 2:3-4",
verses: {
BibleTranslation.esv: "Do nothing from selfish ambition or conceit, but in humility count others more significant than yourselves. Let each of you look not only to his own interests, but also to the interests of others.",
},
reflection: "Humility is the foundation of a happy marriage.",
applicablePhases: ['husband'],
applicableContexts: ['servant', 'humility'],
),
Scripture(
reference: "Proverbs 29:18",
verses: {
BibleTranslation.esv: "Where there is no prophetic vision the people cast off restraint, but blessed is he who keeps the law.",
BibleTranslation.kjv: "Where there is no vision, the people perish: but he that keepeth the law, happy is he.",
},
reflection: "Lead your family with a clear, Godly vision.",
applicablePhases: ['husband'],
applicableContexts: ['vision', 'leadership'],
),
Scripture(
reference: "James 1:5",
verses: {
BibleTranslation.esv: "If any of you lacks wisdom, let him ask God, who gives generously to all without reproach, and it will be given him.",
},
reflection: "Seek God's wisdom in every decision you make for your family.",
applicablePhases: ['husband'],
applicableContexts: ['wisdom', 'vision'],
),
Scripture(
reference: "1 Timothy 3:4-5",
verses: {
BibleTranslation.esv: "He must manage his own household well, with all dignity keeping his children submissive, for if someone does not know how to manage his own household, how will he care for God's church?",
},
reflection: "Your first ministry is your home. Manage it with love and dignity.",
applicablePhases: ['husband'],
applicableContexts: ['leadership'],
),
Scripture(
reference: "Colossians 3:19",
verses: {
BibleTranslation.esv: "Husbands, love your wives, and do not be harsh with them.",
BibleTranslation.niv: "Husbands, love your wives and do not be harsh with them.",
},
reflection: "Gentleness is a sign of strength, not weakness.",
applicablePhases: ['husband'],
applicableContexts: ['kindness', 'love'],
),
Scripture(
reference: "1 Corinthians 16:14",
verses: {
BibleTranslation.esv: "Let all that you do be done in love.",
},
reflection: "Let love be the motivation behind every action and word.",
applicablePhases: ['husband'],
applicableContexts: ['love'],
),
];
Future<void> loadScriptures() async {
_scriptureBox = await Hive.openBox<Scripture>('scriptures');
if (_scriptureBox.isEmpty) {
print('Hive box is empty. Importing scriptures from optimized JSON data...');
// Load the pre-processed JSON file which already contains all verse text
final String response = await rootBundle.loadString('assets/scriptures_optimized.json');
final Map<String, dynamic> data = json.decode(response);
List<Scripture> importedScriptures = [];
// Helper function to process ANY list of scriptures
void processList(List<dynamic> list, String listName) {
for (var jsonEntry in list) {
final reference = jsonEntry['reference'];
final reflection = jsonEntry['reflection']; // Optional
final applicablePhases = (jsonEntry['applicablePhases'] as List<dynamic>?)
?.map((e) => e as String)
.toList() ?? [];
final applicableContexts = (jsonEntry['applicableContexts'] as List<dynamic>?)
?.map((e) => e as String)
.toList() ?? [];
// Map string keys (esv, niv) to BibleTranslation enum
Map<BibleTranslation, String> versesMap = {};
if (jsonEntry['verses'] != null) {
(jsonEntry['verses'] as Map<String, dynamic>).forEach((key, value) {
// Find enum by name (case-insensitive usually, but here keys are lowercase 'esv')
try {
final translation = BibleTranslation.values.firstWhere(
(e) => e.name.toLowerCase() == key.toLowerCase()
);
versesMap[translation] = value.toString();
} catch (e) {
print('Warning: Unknown translation key "$key" in optimized JSON');
}
});
}
if (versesMap.isNotEmpty) {
importedScriptures.add(Scripture(
verses: versesMap,
reference: reference,
reflection: reflection,
applicablePhases: applicablePhases,
applicableContexts: applicableContexts,
));
}
}
}
// Process all sections
if (data['menstrual'] != null) processList(data['menstrual'], 'menstrual');
if (data['follicular'] != null) processList(data['follicular'], 'follicular');
if (data['ovulation'] != null) processList(data['ovulation'], 'ovulation');
if (data['luteal'] != null) processList(data['luteal'], 'luteal');
if (data['husband'] != null) processList(data['husband'], 'husband');
if (data['womanhood'] != null) processList(data['womanhood'], 'womanhood');
if (data['contextual'] != null) {
final contextualMap = data['contextual'] as Map<String, dynamic>;
contextualMap.forEach((key, value) {
processList(value as List, 'contextual_$key');
});
}
// Store all imported scriptures into Hive
for (var scripture in importedScriptures) {
await _scriptureBox.put(scripture.reference, scripture); // Using reference as key
}
} else {
print('Hive box is not empty. Loading scriptures from Hive...');
}
// Populate internal lists from Hive box values
_menstrualScriptures = _scriptureBox.values
.where((s) => s.applicablePhases.contains('menstrual'))
.toList();
_follicularScriptures = _scriptureBox.values
.where((s) => s.applicablePhases.contains('follicular'))
.toList();
_ovulationScriptures = _scriptureBox.values
.where((s) => s.applicablePhases.contains('ovulation'))
.toList();
_lutealScriptures = _scriptureBox.values
.where((s) => s.applicablePhases.contains('luteal'))
.toList();
_husbandScriptures = [
..._scriptureBox.values.where((s) => s.applicablePhases.contains('husband')),
..._hardcodedHusbandScriptures,
];
// Remove duplicates based on reference if any
final uniqueHusbandIds = <String>{};
_husbandScriptures = _husbandScriptures.where((s) {
if (uniqueHusbandIds.contains(s.reference)) return false;
uniqueHusbandIds.add(s.reference);
return true;
}).toList();
_womanhoodScriptures = _scriptureBox.values
.where((s) => s.applicableContexts.contains('womanhood'))
.toList();
_contextualScriptures = {
'anxiety': _scriptureBox.values.where((s) => s.applicableContexts.contains('anxiety')).toList(),
'pain': _scriptureBox.values.where((s) => s.applicableContexts.contains('pain')).toList(),
'fatigue': _scriptureBox.values.where((s) => s.applicableContexts.contains('fatigue')).toList(),
'joy': _scriptureBox.values.where((s) => s.applicableContexts.contains('joy')).toList(),
};
}
/// Get the number of scriptures for a given phase
int getScriptureCountForPhase(String phase) {
switch (phase.toLowerCase()) {
case 'menstrual':
return _menstrualScriptures.length;
case 'follicular':
return _follicularScriptures.length;
case 'ovulation':
return _ovulationScriptures.length;
case 'luteal':
return _lutealScriptures.length;
case 'husband':
return _husbandScriptures.length;
case 'womanhood':
return _womanhoodScriptures.length;
case 'anxiety':
return _contextualScriptures['anxiety']?.length ?? 0;
case 'pain':
return _contextualScriptures['pain']?.length ?? 0;
case 'fatigue':
return _contextualScriptures['fatigue']?.length ?? 0;
case 'joy':
return _contextualScriptures['joy']?.length ?? 0;
default:
return 0;
}
}
/// Get recommended scripture based on entry
static Scripture? getRecommendedScripture(CycleEntry entry) {
if (entry.mood == MoodLevel.verySad || entry.mood == MoodLevel.sad || (entry.stressLevel != null && entry.stressLevel! > 3)) {
return contextualScriptures['anxiety']![DateTime.now().day % contextualScriptures['anxiety']!.length];
Scripture? getRecommendedScripture(CycleEntry entry) {
if (entry.mood == MoodLevel.verySad ||
entry.mood == MoodLevel.sad ||
(entry.stressLevel != null && entry.stressLevel! > 3)) {
final scriptures = _contextualScriptures['anxiety'];
if (scriptures != null && scriptures.isNotEmpty) {
return scriptures[DateTime.now().day % scriptures.length];
}
}
if ((entry.crampIntensity != null && entry.crampIntensity! >= 3) || entry.hasHeadache || entry.hasLowerBackPain) {
return contextualScriptures['pain']![DateTime.now().day % contextualScriptures['pain']!.length];
if ((entry.crampIntensity != null && entry.crampIntensity! >= 3) ||
entry.hasHeadache ||
entry.hasLowerBackPain) {
final scriptures = _contextualScriptures['pain'];
if (scriptures != null && scriptures.isNotEmpty) {
return scriptures[DateTime.now().day % scriptures.length];
}
}
if (entry.hasFatigue || entry.hasInsomnia || (entry.energyLevel != null && entry.energyLevel! <= 2)) {
return contextualScriptures['fatigue']![DateTime.now().day % contextualScriptures['fatigue']!.length];
if (entry.hasFatigue ||
entry.hasInsomnia ||
(entry.energyLevel != null && entry.energyLevel! <= 2)) {
final scriptures = _contextualScriptures['fatigue'];
if (scriptures != null && scriptures.isNotEmpty) {
return scriptures[DateTime.now().day % scriptures.length];
}
}
if (entry.mood == MoodLevel.veryHappy) {
return contextualScriptures['joy']![DateTime.now().day % contextualScriptures['joy']!.length];
final scriptures = _contextualScriptures['joy'];
if (scriptures != null && scriptures.isNotEmpty) {
return scriptures[DateTime.now().day % scriptures.length];
}
}
return null;
}
>>>>>>> 6742220 (Your commit message here)
/// Get scripture for current phase
static Scripture getScriptureForPhase(String phase) {
final List<Scripture> scriptures;
/// Get scripture for current phase by index
Scripture? getScriptureForPhaseByIndex(String phase, int index) {
List<Scripture> scriptures;
switch (phase.toLowerCase()) {
case 'menstrual':
scriptures = menstrualScriptures;
scriptures = _menstrualScriptures;
break;
case 'follicular':
scriptures = follicularScriptures;
scriptures = _follicularScriptures;
break;
case 'ovulation':
scriptures = ovulationScriptures;
scriptures = _ovulationScriptures;
break;
case 'luteal':
scriptures = lutealScriptures;
scriptures = _lutealScriptures;
break;
case 'husband':
scriptures = _husbandScriptures;
break;
case 'womanhood':
scriptures = _womanhoodScriptures;
break;
case 'anxiety':
scriptures = _contextualScriptures['anxiety'] ?? [];
break;
case 'pain':
scriptures = _contextualScriptures['pain'] ?? [];
break;
case 'fatigue':
scriptures = _contextualScriptures['fatigue'] ?? [];
break;
case 'joy':
scriptures = _contextualScriptures['joy'] ?? [];
break;
default:
scriptures = [...menstrualScriptures, ...follicularScriptures, ...ovulationScriptures, ...lutealScriptures];
return null;
}
// Return a scripture based on the day of year for variety
final dayOfYear = DateTime.now().difference(DateTime(DateTime.now().year, 1, 1)).inDays;
return scriptures[dayOfYear % scriptures.length];
if (scriptures.isEmpty || index < 0 || index >= scriptures.length) {
return null;
}
return scriptures[index];
}
/// Get scripture for husband
static Scripture getHusbandScripture() {
final dayOfYear = DateTime.now().difference(DateTime(DateTime.now().year, 1, 1)).inDays;
return husbandScriptures[dayOfYear % husbandScriptures.length];
// ... imports
// ... inside ScriptureDatabase class
/// Get a random scripture for a given phase
Scripture? getRandomScriptureForPhase(String phase) {
List<Scripture> scriptures;
switch (phase.toLowerCase()) {
case 'menstrual':
scriptures = _menstrualScriptures;
break;
case 'follicular':
scriptures = _follicularScriptures;
break;
case 'ovulation':
scriptures = _ovulationScriptures;
break;
case 'luteal':
scriptures = _lutealScriptures;
break;
case 'husband':
scriptures = _husbandScriptures;
break;
case 'womanhood':
scriptures = _womanhoodScriptures;
break;
case 'anxiety':
scriptures = _contextualScriptures['anxiety'] ?? [];
break;
case 'pain':
scriptures = _contextualScriptures['pain'] ?? [];
break;
case 'fatigue':
scriptures = _contextualScriptures['fatigue'] ?? [];
break;
case 'joy':
scriptures = _contextualScriptures['joy'] ?? [];
break;
default:
return null;
}
if (scriptures.isEmpty) {
return null;
}
return scriptures[Random().nextInt(scriptures.length)];
}
/// Get scripture for current phase (Randomized)
Scripture getScriptureForPhase(String phase) {
List<Scripture> scriptures;
switch (phase.toLowerCase()) {
// ... (same switch cases)
case 'menstrual':
scriptures = _menstrualScriptures;
break;
case 'follicular':
scriptures = _follicularScriptures;
break;
case 'ovulation':
scriptures = _ovulationScriptures;
break;
case 'luteal':
scriptures = _lutealScriptures;
break;
case 'husband':
scriptures = _husbandScriptures;
break;
case 'womanhood':
scriptures = _womanhoodScriptures;
break;
case 'anxiety':
scriptures = _contextualScriptures['anxiety'] ?? [];
break;
case 'pain':
scriptures = _contextualScriptures['pain'] ?? [];
break;
case 'fatigue':
scriptures = _contextualScriptures['fatigue'] ?? [];
break;
case 'joy':
scriptures = _contextualScriptures['joy'] ?? [];
break;
default:
// Fallback
scriptures = [
..._menstrualScriptures,
..._follicularScriptures,
..._ovulationScriptures,
..._lutealScriptures,
..._husbandScriptures,
..._womanhoodScriptures,
...(_contextualScriptures['anxiety'] ?? []),
...(_contextualScriptures['pain'] ?? []),
...(_contextualScriptures['fatigue'] ?? []),
...(_contextualScriptures['joy'] ?? []),
];
if (scriptures.isEmpty) return Scripture(verses: {BibleTranslation.esv: "No scripture found."}, reference: "Unknown", applicablePhases: [], applicableContexts: []);
}
if (scriptures.isEmpty) return Scripture(verses: {BibleTranslation.esv: "No scripture found."}, reference: "Unknown", applicablePhases: [], applicableContexts: []);
return scriptures[Random().nextInt(scriptures.length)];
}
/// Get scripture for husband (Randomized)
Scripture getHusbandScripture() {
final scriptures = _husbandScriptures;
if (scriptures.isEmpty) {
return Scripture(verses: {BibleTranslation.esv: "No husband scripture found."}, reference: "Unknown", applicablePhases: [], applicableContexts: []);
}
return scriptures[Random().nextInt(scriptures.length)];
}
/// Get all scriptures
static List<Scripture> getAllScriptures() {
return [
...menstrualScriptures,
...follicularScriptures,
...ovulationScriptures,
...lutealScriptures,
...womanhoodScriptures,
];
List<Scripture> getAllScriptures() {
return _scriptureBox.values.toList();
}
}