160 lines
5.4 KiB
Dart
160 lines
5.4 KiB
Dart
import 'package:flutter/material.dart';
|
|
import '../models/notification_settings.dart';
|
|
|
|
/// Widget pour les paramètres de notification
|
|
///
|
|
/// Permet à l'utilisateur de configurer ses préférences de notification
|
|
|
|
class NotificationSettingsWidget extends StatelessWidget {
|
|
final NotificationSettings settings;
|
|
final Function(NotificationSettings) onSettingsChanged;
|
|
|
|
const NotificationSettingsWidget({
|
|
super.key,
|
|
required this.settings,
|
|
required this.onSettingsChanged,
|
|
});
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return ListView(
|
|
padding: const EdgeInsets.all(16.0),
|
|
children: [
|
|
// Notifications générales
|
|
SwitchListTile(
|
|
title: const Text('Activer les notifications'),
|
|
subtitle: const Text('Recevoir des notifications pour les nouveaux messages'),
|
|
value: settings.enableNotifications,
|
|
onChanged: (value) {
|
|
onSettingsChanged(settings.copyWith(enableNotifications: value));
|
|
},
|
|
),
|
|
|
|
if (settings.enableNotifications) ...[
|
|
// Sons et vibrations
|
|
SwitchListTile(
|
|
title: const Text('Sons'),
|
|
subtitle: const Text('Jouer un son à la réception'),
|
|
value: settings.soundEnabled,
|
|
onChanged: (value) {
|
|
onSettingsChanged(settings.copyWith(soundEnabled: value));
|
|
},
|
|
),
|
|
|
|
SwitchListTile(
|
|
title: const Text('Vibration'),
|
|
subtitle: const Text('Vibrer à la réception'),
|
|
value: settings.vibrationEnabled,
|
|
onChanged: (value) {
|
|
onSettingsChanged(settings.copyWith(vibrationEnabled: value));
|
|
},
|
|
),
|
|
|
|
// Aperçu des messages
|
|
SwitchListTile(
|
|
title: const Text('Aperçu du message'),
|
|
subtitle: const Text('Afficher le contenu dans la notification'),
|
|
value: settings.showPreview,
|
|
onChanged: (value) {
|
|
onSettingsChanged(settings.copyWith(showPreview: value));
|
|
},
|
|
),
|
|
|
|
const Divider(),
|
|
|
|
// Mode Ne pas déranger
|
|
SwitchListTile(
|
|
title: const Text('Ne pas déranger'),
|
|
subtitle: settings.doNotDisturb && settings.doNotDisturbStart != null
|
|
? Text('Actif de ${_formatTime(settings.doNotDisturbStart!)} à ${_formatTime(settings.doNotDisturbEnd!)}')
|
|
: null,
|
|
value: settings.doNotDisturb,
|
|
onChanged: (value) {
|
|
if (value) {
|
|
_showTimeRangePicker(context);
|
|
} else {
|
|
onSettingsChanged(settings.copyWith(doNotDisturb: false));
|
|
}
|
|
},
|
|
),
|
|
|
|
if (settings.doNotDisturb)
|
|
ListTile(
|
|
title: const Text('Horaires'),
|
|
subtitle: Text('${_formatTime(settings.doNotDisturbStart!)} - ${_formatTime(settings.doNotDisturbEnd!)}'),
|
|
trailing: const Icon(Icons.arrow_forward_ios),
|
|
onTap: () => _showTimeRangePicker(context),
|
|
),
|
|
|
|
const Divider(),
|
|
|
|
// Conversations en silencieux
|
|
if (settings.mutedConversations.isNotEmpty) ...[
|
|
const ListTile(
|
|
title: Text('Conversations en silencieux'),
|
|
subtitle: Text('Ces conversations n\'enverront pas de notifications'),
|
|
),
|
|
...settings.mutedConversations.map(
|
|
(conversationId) => ListTile(
|
|
title: Text('Conversation $conversationId'), // TODO: Récupérer le vrai nom
|
|
trailing: IconButton(
|
|
icon: const Icon(Icons.volume_up),
|
|
onPressed: () {
|
|
final muted = List<String>.from(settings.mutedConversations);
|
|
muted.remove(conversationId);
|
|
onSettingsChanged(settings.copyWith(mutedConversations: muted));
|
|
},
|
|
),
|
|
),
|
|
),
|
|
],
|
|
],
|
|
],
|
|
);
|
|
}
|
|
|
|
String _formatTime(DateTime time) {
|
|
return '${time.hour.toString().padLeft(2, '0')}:${time.minute.toString().padLeft(2, '0')}';
|
|
}
|
|
|
|
Future<void> _showTimeRangePicker(BuildContext context) async {
|
|
TimeOfDay? startTime = await showTimePicker(
|
|
context: context,
|
|
initialTime: settings.doNotDisturbStart != null
|
|
? TimeOfDay.fromDateTime(settings.doNotDisturbStart!)
|
|
: const TimeOfDay(hour: 22, minute: 0),
|
|
helpText: 'Heure de début',
|
|
);
|
|
|
|
if (startTime != null) {
|
|
final now = DateTime.now();
|
|
final start = DateTime(now.year, now.month, now.day, startTime.hour, startTime.minute);
|
|
|
|
TimeOfDay? endTime = await showTimePicker(
|
|
context: context,
|
|
initialTime: settings.doNotDisturbEnd != null
|
|
? TimeOfDay.fromDateTime(settings.doNotDisturbEnd!)
|
|
: const TimeOfDay(hour: 8, minute: 0),
|
|
helpText: 'Heure de fin',
|
|
);
|
|
|
|
if (endTime != null) {
|
|
DateTime end = DateTime(now.year, now.month, now.day, endTime.hour, endTime.minute);
|
|
|
|
// Si l'heure de fin est avant l'heure de début, on considère qu'elle est le lendemain
|
|
if (end.isBefore(start)) {
|
|
end = end.add(const Duration(days: 1));
|
|
}
|
|
|
|
onSettingsChanged(
|
|
settings.copyWith(
|
|
doNotDisturb: true,
|
|
doNotDisturbStart: start,
|
|
doNotDisturbEnd: end,
|
|
),
|
|
);
|
|
}
|
|
}
|
|
}
|
|
}
|