Resolve all lints and deprecation warnings

This commit is contained in:
2026-01-09 10:04:51 -06:00
parent 512577b092
commit a799e9cf59
56 changed files with 2819 additions and 3159 deletions

View File

@@ -137,7 +137,7 @@ class HusbandAppearanceScreen extends ConsumerWidget {
boxShadow: [
if (isSelected)
BoxShadow(
color: color.withOpacity(0.4),
color: color.withValues(alpha: 0.4),
blurRadius: 8,
offset: const Offset(0, 4),
)

View File

@@ -8,6 +8,7 @@ import '../../providers/user_provider.dart';
import '../../theme/app_theme.dart';
import '../../services/bible_xml_parser.dart';
import '../../services/mock_data_service.dart';
import '../../services/notification_service.dart';
class HusbandDevotionalScreen extends ConsumerStatefulWidget {
const HusbandDevotionalScreen({super.key});
@@ -190,11 +191,11 @@ class _HusbandDevotionalScreenState
// Trigger notification for new teaching plans
if (existingPlan == null) {
NotificationService().showTeachingPlanNotification(
teacherName: user.name ?? 'Husband',
teacherName: user.name,
);
}
if (mounted) Navigator.pop(context);
if (context.mounted) Navigator.pop(context);
},
child: const Text('Save'),
),
@@ -283,7 +284,7 @@ class _HusbandDevotionalScreenState
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(16),
border: Border.all(color: Colors.grey.withOpacity(0.2)),
border: Border.all(color: Colors.grey.withValues(alpha: 0.2)),
),
child: Column(
children: [
@@ -314,7 +315,7 @@ class _HusbandDevotionalScreenState
background: Container(
alignment: Alignment.centerRight,
padding: const EdgeInsets.only(right: 20),
color: Colors.red.withOpacity(0.8),
color: Colors.red.withValues(alpha: 0.8),
child: const Icon(Icons.delete, color: Colors.white),
),
onDismissed: (_) => _deletePlan(plan),
@@ -517,14 +518,14 @@ class _HusbandDevotionalScreenState
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [
AppColors.lavender.withOpacity(0.15),
AppColors.blushPink.withOpacity(0.15),
AppColors.lavender.withValues(alpha: 0.15),
AppColors.blushPink.withValues(alpha: 0.15),
],
begin: Alignment.topLeft,
end: Alignment.bottomRight,
),
borderRadius: BorderRadius.circular(16),
border: Border.all(color: AppColors.lavender.withOpacity(0.3)),
border: Border.all(color: AppColors.lavender.withValues(alpha: 0.3)),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
@@ -623,12 +624,12 @@ class _HusbandDevotionalScreenState
width: double.infinity,
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
color: Colors.white.withOpacity(0.5),
color: Colors.white.withValues(alpha: 0.5),
borderRadius: BorderRadius.circular(12),
),
child: Column(
children: [
Icon(Icons.favorite_border,
const Icon(Icons.favorite_border,
color: AppColors.warmGray, size: 32),
const SizedBox(height: 8),
Text(
@@ -642,7 +643,7 @@ class _HusbandDevotionalScreenState
'Check back later or encourage her to share.',
style: GoogleFonts.outfit(
fontSize: 12,
color: AppColors.warmGray.withOpacity(0.8),
color: AppColors.warmGray.withValues(alpha: 0.8),
),
),
],
@@ -660,8 +661,8 @@ class _HusbandDevotionalScreenState
showDialog(
context: context,
builder: (context) => AlertDialog(
title: Row(
children: const [
title: const Row(
children: [
Icon(Icons.link, color: AppColors.navyBlue),
SizedBox(width: 8),
Text('Connect with Wife'),
@@ -723,12 +724,14 @@ class _HusbandDevotionalScreenState
.updateProfile(updatedProfile);
}
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text('Connected with wife! 💑'),
backgroundColor: AppColors.sageGreen,
),
);
if (context.mounted) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text('Connected with wife! 💑'),
backgroundColor: AppColors.sageGreen,
),
);
}
}
},
style: ElevatedButton.styleFrom(

File diff suppressed because it is too large Load Diff

View File

@@ -1,10 +1,9 @@
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
import '../../theme/app_theme.dart';
import './learn_article_screen.dart';
import '../../data/learn_content.dart';
class _HusbandLearnScreen extends StatelessWidget {
const _HusbandLearnScreen();
class HusbandLearnArticlesScreen extends StatelessWidget {
const HusbandLearnArticlesScreen({super.key});
@override
Widget build(BuildContext context) {
@@ -23,7 +22,7 @@ class _HusbandLearnScreen extends StatelessWidget {
),
),
const SizedBox(height: 24),
_buildSection(context, 'Understanding Her', [
_buildSection(context, 'Understanding Her', const [
_LearnItem(
icon: Icons.loop,
title: 'The 4 Phases of Her Cycle',
@@ -44,7 +43,7 @@ class _HusbandLearnScreen extends StatelessWidget {
),
]),
const SizedBox(height: 24),
_buildSection(context, 'Biblical Manhood', [
_buildSection(context, 'Biblical Manhood', const [
_LearnItem(
icon: Icons.favorite,
title: 'Loving Like Christ',
@@ -65,7 +64,7 @@ class _HusbandLearnScreen extends StatelessWidget {
),
]),
const SizedBox(height: 24),
_buildSection(context, 'NFP for Husbands', [
_buildSection(context, 'NFP for Husbands', const [
_LearnItem(
icon: Icons.show_chart,
title: 'Reading the Charts Together',
@@ -85,7 +84,8 @@ class _HusbandLearnScreen extends StatelessWidget {
);
}
Widget _buildSection(BuildContext context, String title, List<_LearnItem> items) {
Widget _buildSection(
BuildContext context, String title, List<_LearnItem> items) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
@@ -111,7 +111,10 @@ class _HusbandLearnScreen extends StatelessWidget {
width: 40,
height: 40,
decoration: BoxDecoration(
color: Theme.of(context).colorScheme.primary.withOpacity(0.1),
color: Theme.of(context)
.colorScheme
.primary
.withValues(alpha: 0.1),
borderRadius: BorderRadius.circular(10),
),
child: Icon(
@@ -143,7 +146,9 @@ class _HusbandLearnScreen extends StatelessWidget {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => LearnArticleScreen(articleId: item.articleId),
builder: (context) =>
CombinedLearnArticleDetailScreen(
articleId: item.articleId),
),
);
},
@@ -168,4 +173,148 @@ class _LearnItem {
required this.subtitle,
required this.articleId,
});
}
}
class CombinedLearnArticleDetailScreen extends StatelessWidget {
final String articleId;
const CombinedLearnArticleDetailScreen({super.key, required this.articleId});
@override
Widget build(BuildContext context) {
final article = LearnContent.getArticle(articleId);
if (article == null) {
return Scaffold(
appBar: AppBar(title: const Text('Article Not Found')),
body: const Center(child: Text('Article not found')),
);
}
return Scaffold(
backgroundColor: Theme.of(context).scaffoldBackgroundColor,
appBar: AppBar(
backgroundColor: Theme.of(context).scaffoldBackgroundColor,
elevation: 0,
leading: IconButton(
icon:
Icon(Icons.arrow_back, color: Theme.of(context).iconTheme.color),
onPressed: () => Navigator.pop(context),
),
title: Text(
article.category,
style: GoogleFonts.outfit(
fontSize: 14,
fontWeight: FontWeight.w500,
color: Theme.of(context).textTheme.bodySmall?.color,
),
),
centerTitle: true,
),
body: SingleChildScrollView(
padding: const EdgeInsets.all(20),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
article.title,
style: GoogleFonts.outfit(
fontSize: 26,
fontWeight: FontWeight.w700,
color: Theme.of(context).textTheme.headlineMedium?.color,
height: 1.2,
),
),
const SizedBox(height: 8),
Text(
article.subtitle,
style: GoogleFonts.outfit(
fontSize: 15,
color: Theme.of(context).textTheme.bodyMedium?.color,
),
),
const SizedBox(height: 24),
Container(
height: 3,
width: 40,
decoration: BoxDecoration(
color: Theme.of(context).colorScheme.primary,
borderRadius: BorderRadius.circular(2),
),
),
const SizedBox(height: 24),
...article.sections
.map((section) => _buildSection(context, section)),
],
),
),
);
}
Widget _buildSection(BuildContext context, LearnSection section) {
return Padding(
padding: const EdgeInsets.only(bottom: 24),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
if (section.heading != null) ...[
Text(
section.heading!,
style: GoogleFonts.outfit(
fontSize: 17,
fontWeight: FontWeight.w600,
color: Theme.of(context).textTheme.titleLarge?.color,
),
),
const SizedBox(height: 10),
],
_buildRichText(context, section.content),
],
),
);
}
Widget _buildRichText(BuildContext context, String content) {
final List<InlineSpan> spans = [];
final RegExp boldPattern = RegExp(r'\*\*(.*?)\*\*');
int currentIndex = 0;
for (final match in boldPattern.allMatches(content)) {
if (match.start > currentIndex) {
spans.add(TextSpan(
text: content.substring(currentIndex, match.start),
style: GoogleFonts.outfit(
fontSize: 15,
color: Theme.of(context).textTheme.bodyLarge?.color,
height: 1.7,
),
));
}
spans.add(TextSpan(
text: match.group(1),
style: GoogleFonts.outfit(
fontSize: 15,
fontWeight: FontWeight.w600,
color: Theme.of(context).textTheme.titleMedium?.color,
height: 1.7,
),
));
currentIndex = match.end;
}
if (currentIndex < content.length) {
spans.add(TextSpan(
text: content.substring(currentIndex),
style: GoogleFonts.outfit(
fontSize: 15,
color: Theme.of(context).textTheme.bodyLarge?.color,
height: 1.7,
),
));
}
return RichText(
text: TextSpan(children: spans),
);
}
}

View File

@@ -2,7 +2,6 @@ import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:intl/intl.dart';
import '../../models/cycle_entry.dart';
import '../../providers/user_provider.dart';
class HusbandNotesScreen extends ConsumerWidget {
@@ -16,7 +15,7 @@ class HusbandNotesScreen extends ConsumerWidget {
(entry.notes != null && entry.notes!.isNotEmpty) ||
(entry.husbandNotes != null && entry.husbandNotes!.isNotEmpty))
.toList();
// Sort entries by date, newest first
notesEntries.sort((a, b) => b.date.compareTo(a.date));
@@ -33,7 +32,8 @@ class HusbandNotesScreen extends ConsumerWidget {
itemBuilder: (context, index) {
final entry = notesEntries[index];
return Card(
margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
margin:
const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
@@ -41,9 +41,10 @@ class HusbandNotesScreen extends ConsumerWidget {
children: [
Text(
DateFormat.yMMMMd().format(entry.date),
style: Theme.of(context).textTheme.titleMedium?.copyWith(
fontWeight: FontWeight.bold,
),
style:
Theme.of(context).textTheme.titleMedium?.copyWith(
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 12),
if (entry.notes != null && entry.notes!.isNotEmpty)
@@ -51,7 +52,8 @@ class HusbandNotesScreen extends ConsumerWidget {
title: 'Her Notes',
content: entry.notes!,
),
if (entry.husbandNotes != null && entry.husbandNotes!.isNotEmpty)
if (entry.husbandNotes != null &&
entry.husbandNotes!.isNotEmpty)
_NoteSection(
title: 'Your Notes',
content: entry.husbandNotes!,
@@ -93,4 +95,4 @@ class _NoteSection extends StatelessWidget {
],
);
}
}
}

View File

@@ -147,11 +147,11 @@ class HusbandSettingsScreen extends ConsumerWidget {
context: context,
builder: (context) => StatefulBuilder(
builder: (context, setState) => AlertDialog(
title: Row(
title: const Row(
children: [
const Icon(Icons.link, color: AppColors.navyBlue),
const SizedBox(width: 8),
const Text('Connect with Wife'),
Icon(Icons.link, color: AppColors.navyBlue),
SizedBox(width: 8),
Text('Connect with Wife'),
],
),
content: Column(
@@ -188,7 +188,7 @@ class HusbandSettingsScreen extends ConsumerWidget {
value: shareDevotional,
onChanged: (val) =>
setState(() => shareDevotional = val ?? true),
activeColor: AppColors.navyBlue,
activeColor: AppColors.sageGreen,
),
),
const SizedBox(width: 12),
@@ -233,12 +233,14 @@ class HusbandSettingsScreen extends ConsumerWidget {
user.copyWith(isDataShared: shareDevotional));
}
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text('Settings updated & Connected!'),
backgroundColor: AppColors.sageGreen,
),
);
if (context.mounted) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text('Settings updated & Connected!'),
backgroundColor: AppColors.sageGreen,
),
);
}
if (code.isNotEmpty) {
// Load demo data as simulation
@@ -281,7 +283,7 @@ class HusbandSettingsScreen extends ConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
// Theme aware colors
final isDark = Theme.of(context).brightness == Brightness.dark;
final cardColor =
Theme.of(context).cardTheme.color; // Using theme card color
final textColor = Theme.of(context).textTheme.bodyLarge?.color;

View File

@@ -1,156 +0,0 @@
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
import '../../data/learn_content.dart';
import '../../theme/app_theme.dart';
/// Screen to display full learn article content
class LearnArticleScreen extends StatelessWidget {
final String articleId;
const LearnArticleScreen({super.key, required this.articleId});
@override
Widget build(BuildContext context) {
final article = LearnContent.getArticle(articleId);
if (article == null) {
return Scaffold(
appBar: AppBar(title: const Text('Article Not Found')),
body: const Center(child: Text('Article not found')),
);
}
return Scaffold(
backgroundColor: Theme.of(context).scaffoldBackgroundColor,
appBar: AppBar(
backgroundColor: Theme.of(context).scaffoldBackgroundColor,
elevation: 0,
leading: IconButton(
icon: Icon(Icons.arrow_back, color: Theme.of(context).iconTheme.color),
onPressed: () => Navigator.pop(context),
),
title: Text(
article.category,
style: GoogleFonts.outfit(
fontSize: 14,
fontWeight: FontWeight.w500,
color: Theme.of(context).textTheme.bodySmall?.color,
),
),
centerTitle: true,
),
body: SingleChildScrollView(
padding: const EdgeInsets.all(20),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// Title
Text(
article.title,
style: GoogleFonts.outfit(
fontSize: 26,
fontWeight: FontWeight.w700,
color: Theme.of(context).textTheme.headlineMedium?.color,
height: 1.2,
),
),
const SizedBox(height: 8),
Text(
article.subtitle,
style: GoogleFonts.outfit(
fontSize: 15,
color: Theme.of(context).textTheme.bodyMedium?.color,
),
),
const SizedBox(height: 24),
// Divider
Container(
height: 3,
width: 40,
decoration: BoxDecoration(
color: Theme.of(context).colorScheme.primary,
borderRadius: BorderRadius.circular(2),
),
),
const SizedBox(height: 24),
// Sections
...article.sections.map((section) => _buildSection(context, section)),
],
),
),
);
}
Widget _buildSection(BuildContext context, LearnSection section) {
return Padding(
padding: const EdgeInsets.only(bottom: 24),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
if (section.heading != null) ...[
Text(
section.heading!,
style: GoogleFonts.outfit(
fontSize: 17,
fontWeight: FontWeight.w600,
color: Theme.of(context).textTheme.titleLarge?.color,
),
),
const SizedBox(height: 10),
],
_buildRichText(context, section.content),
],
),
);
}
Widget _buildRichText(BuildContext context, String content) {
// Handle basic markdown-like formatting
final List<InlineSpan> spans = [];
final RegExp boldPattern = RegExp(r'\*\*(.*?)\*\*');
int currentIndex = 0;
for (final match in boldPattern.allMatches(content)) {
// Add text before the match
if (match.start > currentIndex) {
spans.add(TextSpan(
text: content.substring(currentIndex, match.start),
style: GoogleFonts.outfit(
fontSize: 15,
color: Theme.of(context).textTheme.bodyLarge?.color,
height: 1.7,
),
));
}
// Add bold text
spans.add(TextSpan(
text: match.group(1),
style: GoogleFonts.outfit(
fontSize: 15,
fontWeight: FontWeight.w600,
color: Theme.of(context).textTheme.titleMedium?.color,
height: 1.7,
),
));
currentIndex = match.end;
}
// Add remaining text
if (currentIndex < content.length) {
spans.add(TextSpan(
text: content.substring(currentIndex),
style: GoogleFonts.outfit(
fontSize: 15,
color: Theme.of(context).textTheme.bodyLarge?.color,
height: 1.7,
),
));
}
return RichText(
text: TextSpan(children: spans),
);
}
}