Files
AutoJudge-Flutter/lib/services/notification_service.dart
2025-11-13 09:14:49 +08:00

204 lines
5.8 KiB
Dart

import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:flutter/foundation.dart';
/// Service for managing local notifications
/// Handles batch evaluation progress notifications and completion alerts
///
/// Usage example:
/// ```dart
/// final notificationService = NotificationService();
/// await notificationService.initialize();
///
/// // Set up tap callback
/// notificationService.onNotificationTapped = (payload) {
/// // Handle navigation based on payload
/// if (payload == 'batch_complete') {
/// // Navigate to results screen
/// }
/// };
///
/// // Show batch start notification
/// await notificationService.showBatchStartNotification(10);
///
/// // Update progress
/// await notificationService.updateProgressNotification(
/// current: 5,
/// total: 10,
/// courseName: '高等数学',
/// );
///
/// // Show completion
/// await notificationService.showCompletionNotification(
/// success: 9,
/// failed: 1,
/// total: 10,
/// );
/// ```
class NotificationService {
static const String _channelId = 'evaluation_progress';
static const String _channelName = '评教进度';
static const String _channelDescription = '显示批量评教的实时进度';
static const int _batchNotificationId = 1000;
static const int _progressNotificationId = 1001;
static const int _completionNotificationId = 1002;
static const int _errorNotificationId = 1003;
final FlutterLocalNotificationsPlugin _notifications;
bool _isInitialized = false;
// Callback for when notification is tapped
Function(String?)? onNotificationTapped;
NotificationService() : _notifications = FlutterLocalNotificationsPlugin();
/// Initialize the notification service
///
/// Configures notification channels for Android and iOS
/// Sets up notification icons and default settings
///
/// Returns true if initialization succeeds, false otherwise
Future<bool> initialize() async {
if (_isInitialized) {
return true;
}
try {
// Android initialization settings
const androidSettings = AndroidInitializationSettings(
'@mipmap/ic_launcher',
);
// iOS initialization settings
const iosSettings = DarwinInitializationSettings(
requestAlertPermission: true,
requestBadgePermission: true,
requestSoundPermission: true,
);
// Combined initialization settings
const initSettings = InitializationSettings(
android: androidSettings,
iOS: iosSettings,
);
// Initialize the plugin
final initialized = await _notifications.initialize(
initSettings,
onDidReceiveNotificationResponse: _onNotificationTapped,
onDidReceiveBackgroundNotificationResponse: _onNotificationTapped,
);
if (initialized == true) {
// Create notification channel for Android
await _createNotificationChannel();
_isInitialized = true;
return true;
}
return false;
} catch (e) {
debugPrint('Failed to initialize notification service: $e');
return false;
}
}
/// Create Android notification channel
///
/// Sets up a high-priority channel for evaluation progress notifications
Future<void> _createNotificationChannel() async {
const androidChannel = AndroidNotificationChannel(
_channelId,
_channelName,
description: _channelDescription,
importance: Importance.high,
enableVibration: true,
playSound: true,
);
await _notifications
.resolvePlatformSpecificImplementation<
AndroidFlutterLocalNotificationsPlugin
>()
?.createNotificationChannel(androidChannel);
}
/// Handle notification tap events
///
/// Called when user taps on a notification
/// Triggers the callback to allow navigation to specific screens
void _onNotificationTapped(NotificationResponse response) {
debugPrint('Notification tapped: ${response.payload}');
// Trigger the callback if set
if (onNotificationTapped != null) {
onNotificationTapped!(response.payload);
}
}
/// Check if the service is initialized
bool get isInitialized => _isInitialized;
/// Show notification when batch evaluation starts
///
/// [totalCourses] - Total number of courses to evaluate
Future<void> showBatchStartNotification(int totalCourses) async {
// Notification service disabled
return;
}
/// Update progress notification with current status
///
/// Shows a progress bar and current course being evaluated
///
/// [current] - Number of courses completed
/// [total] - Total number of courses
/// [courseName] - Name of the current course being evaluated
Future<void> updateProgressNotification({
required int current,
required int total,
required String courseName,
}) async {
// Notification service disabled
return;
}
/// Show completion notification with final statistics
///
/// [success] - Number of successfully evaluated courses
/// [failed] - Number of failed evaluations
/// [total] - Total number of courses
Future<void> showCompletionNotification({
required int success,
required int failed,
required int total,
}) async {
// Notification service disabled
return;
}
/// Show error notification
///
/// [message] - Error message to display
Future<void> showErrorNotification(String message) async {
// Notification service disabled
return;
}
/// Cancel all active notifications
///
/// Clears all notifications from the notification tray
Future<void> cancelAll() async {
if (!_isInitialized) {
debugPrint('Notification service not initialized');
return;
}
try {
await _notifications.cancelAll();
} catch (e) {
debugPrint('Failed to cancel notifications: $e');
}
}
}