save_points_background_service_builder 0.0.6
save_points_background_service_builder: ^0.0.6 copied to clipboard
A Flutter package to easily build and manage background services and notifications, optimized for Save Points.
example/lib/main.dart
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:save_points_background_service_builder/save_points_background_service_builder.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
// Initialize SharedPreferences for persistence
final prefs = await SharedPreferences.getInstance();
runApp(
ProviderScope(
overrides: [
// Required for the package to access local storage
sharedPreferencesProvider.overrideWithValue(prefs),
],
child: const NotificationExampleApp(),
),
);
}
class NotificationExampleApp extends StatefulWidget {
const NotificationExampleApp({super.key});
@override
State<NotificationExampleApp> createState() => _NotificationExampleAppState();
}
class _NotificationExampleAppState extends State<NotificationExampleApp> {
List<NotificationModel> list = [
NotificationModel(
id: '111',
title: '48',
body: 'body 48',
scheduleTime: DateTime(2026, 2, 4, 10, 1),
type: NotificationScheduleType.oneTime,
),
];
int id = 13;
///
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Background Service Example',
debugShowCheckedModeBanner: false,
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: const Color(0xFF673AB7)),
useMaterial3: true,
fontFamily: 'Inter',
),
darkTheme: ThemeData(
colorScheme: ColorScheme.fromSeed(
seedColor: const Color(0xFF673AB7),
brightness: Brightness.dark,
),
useMaterial3: true,
fontFamily: 'Inter',
),
// home: const ExampleDashboard(),
home: Scaffold(
body: NotificationListScreen(
notifications: list,
itemBuilder: (context, notification, notifer) {
return ListTile(
title: Text(notification.title),
subtitle: Text('id ${notification.id}'),
onTap: () async {
setState(() {
list.add(
NotificationModel(
id: '${list.length} + $id',
title: 'title of ${notification.title}',
body: 'body of ${notification.body}',
scheduleTime: DateTime(2026, 2, 4, 11, id),
type: NotificationScheduleType.oneTime,
),
);
id += 5;
notifer.scheduleNotification(notification);
});
},
);
},
),
),
);
}
}
// class ExampleDashboard extends ConsumerWidget {
// const ExampleDashboard({super.key});
// @override
// Widget build(BuildContext context, WidgetRef ref) {
// final notifications = ref.watch(notificationsProvider);
// // Listen to notification taps globally
// ref.listen(notificationTapProvider, (previous, next) {
// next.whenData((response) {
// if (!context.mounted) return;
// ScaffoldMessenger.of(context).showSnackBar(
// SnackBar(
// content: Text('Notification Tapped: ${response.payload}'),
// backgroundColor: Colors.green,
// behavior: SnackBarBehavior.floating,
// ),
// );
// });
// });
// return Scaffold(
// appBar: AppBar(
// title: const Text('Notification Center'),
// centerTitle: true,
// ),
// body: SingleChildScrollView(
// padding: const EdgeInsets.all(20),
// child: Column(
// crossAxisAlignment: CrossAxisAlignment.start,
// children: [
// _buildQuickActionCard(
// context,
// title: 'Schedule New Notification',
// subtitle: 'Create a one-time or recurring reminder',
// icon: Icons.add_alarm_rounded,
// color: Theme.of(context).colorScheme.primaryContainer,
// onTap: () => NotificationSchedulerSheet.show(context),
// ),
// const SizedBox(height: 16),
// _buildQuickActionCard(
// context,
// title: 'View Active Notifications',
// subtitle: 'Manage and cancel your scheduled alerts',
// icon: Icons.list_alt_rounded,
// color: Theme.of(context).colorScheme.secondaryContainer,
// onTap: () => Navigator.of(context).push(
// MaterialPageRoute(
// builder: (_) => NotificationListScreen(
// itemBuilder: (context, notification) {
// return Card(
// margin: const EdgeInsets.symmetric(
// horizontal: 16,
// vertical: 6,
// ),
// child: ListTile(
// title: Text(
// notification.title,
// style: const TextStyle(fontWeight: FontWeight.bold),
// ),
// subtitle: Text(
// '${notification.body}\nType: ${notification.type.name.toUpperCase()}',
// ),
// isThreeLine: true,
// trailing: IconButton(
// icon: const Icon(
// Icons.delete_outline,
// color: Colors.redAccent,
// ),
// onPressed: () {
// ref
// .read(notificationsProvider.notifier)
// .removeNotification(notification.id);
// },
// ),
// ),
// );
// },
// ),
// ),
// ),
// ),
// const SizedBox(height: 32),
// Text(
// 'Quick Status',
// style: Theme.of(
// context,
// ).textTheme.titleLarge?.copyWith(fontWeight: FontWeight.bold),
// ),
// const SizedBox(height: 16),
// notifications.when(
// data: (list) => _buildStatusGrid(context, list.length),
// loading: () => const Center(child: CircularProgressIndicator()),
// error: (e, _) => Text('Error: $e'),
// ),
// const SizedBox(height: 32),
// _buildTestSection(context, ref),
// ],
// ),
// ),
// );
// }
// Widget _buildQuickActionCard(
// BuildContext context, {
// required String title,
// required String subtitle,
// required IconData icon,
// required Color color,
// required VoidCallback onTap,
// }) {
// return InkWell(
// onTap: onTap,
// borderRadius: BorderRadius.circular(20),
// child: Container(
// padding: const EdgeInsets.all(24),
// decoration: BoxDecoration(
// color: color,
// borderRadius: BorderRadius.circular(20),
// boxShadow: [
// BoxShadow(
// color: color.withValues(alpha: 0.3),
// blurRadius: 10,
// offset: const Offset(0, 4),
// ),
// ],
// ),
// child: Row(
// children: [
// Container(
// padding: const EdgeInsets.all(12),
// decoration: BoxDecoration(
// color: Colors.white24,
// borderRadius: BorderRadius.circular(12),
// ),
// child: Icon(icon, size: 32),
// ),
// const SizedBox(width: 20),
// Expanded(
// child: Column(
// crossAxisAlignment: CrossAxisAlignment.start,
// children: [
// Text(
// title,
// style: Theme.of(context).textTheme.titleMedium?.copyWith(
// fontWeight: FontWeight.bold,
// ),
// ),
// Text(subtitle, style: Theme.of(context).textTheme.bodySmall),
// ],
// ),
// ),
// const Icon(Icons.chevron_right_rounded),
// ],
// ),
// ),
// );
// }
// Widget _buildStatusGrid(BuildContext context, int count) {
// return GridView.count(
// shrinkWrap: true,
// crossAxisCount: 2,
// crossAxisSpacing: 16,
// mainAxisSpacing: 16,
// childAspectRatio: 1.5,
// physics: const NeverScrollableScrollPhysics(),
// children: [
// _buildStatItem(
// context,
// 'Active Notifications',
// count.toString(),
// Icons.notifications_active_outlined,
// ),
// _buildStatItem(
// context,
// 'System Status',
// 'Healthy',
// Icons.check_circle_outline_rounded,
// ),
// ],
// );
// }
// Widget _buildStatItem(
// BuildContext context,
// String label,
// String value,
// IconData icon,
// ) {
// return Container(
// padding: const EdgeInsets.all(16),
// decoration: BoxDecoration(
// border: Border.all(color: Theme.of(context).dividerColor),
// borderRadius: BorderRadius.circular(16),
// ),
// child: Column(
// crossAxisAlignment: CrossAxisAlignment.start,
// mainAxisAlignment: MainAxisAlignment.center,
// children: [
// Icon(icon, size: 20, color: Theme.of(context).colorScheme.primary),
// const SizedBox(height: 8),
// Text(
// value,
// style: Theme.of(
// context,
// ).textTheme.headlineSmall?.copyWith(fontWeight: FontWeight.bold),
// ),
// Text(label, style: Theme.of(context).textTheme.labelSmall),
// ],
// ),
// );
// }
// Widget _buildTestSection(BuildContext context, WidgetRef ref) {
// return Container(
// padding: const EdgeInsets.all(20),
// decoration: BoxDecoration(
// color: Theme.of(context).colorScheme.primary.withValues(alpha: 0.15),
// borderRadius: BorderRadius.circular(20),
// ),
// child: Column(
// crossAxisAlignment: CrossAxisAlignment.stretch,
// children: [
// Row(
// children: [
// const Icon(Icons.bug_report_outlined),
// const SizedBox(width: 12),
// Text(
// 'Developer Tools',
// style: Theme.of(context).textTheme.titleMedium,
// ),
// ],
// ),
// const SizedBox(height: 16),
// FilledButton.icon(
// onPressed: () async {
// final service = ref.read(notificationServiceProvider);
// await service.showImmediateNotification(
// title: 'Instant Test',
// body: 'The notification system is working perfectly!',
// );
// },
// icon: const Icon(Icons.flash_on_rounded),
// label: const Text('Test Immediate Notification'),
// ),
// const SizedBox(height: 8),
// OutlinedButton.icon(
// onPressed: () {
// ref.read(notificationsProvider.notifier).initializeSystem();
// ScaffoldMessenger.of(context).showSnackBar(
// const SnackBar(content: Text('Permissions re-requested')),
// );
// },
// icon: const Icon(Icons.security_rounded),
// label: const Text('Re-initialize Permissions'),
// ),
// ],
// ),
// );
// }
// }