- Added TripInvitationRepository for managing trip invitations. - Created TripInvitation model with serialization methods. - Implemented notification payload parser for handling FCM notifications. - Enhanced NotificationService to manage trip invitations and related actions. - Updated UserRepository to include user search functionality. - Modified AuthRepository to store multiple FCM tokens. - Added tests for trip invitation logic and notification payload parsing. - Updated pubspec.yaml and pubspec.lock for dependency management.
147 lines
4.3 KiB
Dart
147 lines
4.3 KiB
Dart
import 'package:cloud_firestore/cloud_firestore.dart';
|
|
|
|
/// Représente une invitation d'un utilisateur à rejoindre un voyage.
|
|
///
|
|
/// Une invitation passe par les statuts `pending`, `accepted` ou `rejected`.
|
|
/// Elle contient le contexte minimum nécessaire pour envoyer les notifications
|
|
/// et appliquer la réponse (trip, expéditeur, destinataire).
|
|
class TripInvitation {
|
|
/// Identifiant Firestore de l'invitation.
|
|
final String id;
|
|
|
|
/// Identifiant du voyage concerné.
|
|
final String tripId;
|
|
|
|
/// Titre du voyage au moment de l'invitation.
|
|
final String tripTitle;
|
|
|
|
/// Identifiant de l'utilisateur qui invite.
|
|
final String inviterId;
|
|
|
|
/// Nom affiché de l'utilisateur qui invite.
|
|
final String inviterName;
|
|
|
|
/// Identifiant de l'utilisateur invité.
|
|
final String inviteeId;
|
|
|
|
/// Email de l'utilisateur invité (utile pour affichage et debug).
|
|
final String inviteeEmail;
|
|
|
|
/// Statut courant de l'invitation: `pending`, `accepted`, `rejected`.
|
|
final String status;
|
|
|
|
/// Date de création de l'invitation.
|
|
final DateTime createdAt;
|
|
|
|
/// Date de réponse (acceptation/refus), null si encore en attente.
|
|
final DateTime? respondedAt;
|
|
|
|
/// Crée une instance de [TripInvitation].
|
|
///
|
|
/// [status] vaut `pending` par défaut pour une nouvelle invitation.
|
|
TripInvitation({
|
|
required this.id,
|
|
required this.tripId,
|
|
required this.tripTitle,
|
|
required this.inviterId,
|
|
required this.inviterName,
|
|
required this.inviteeId,
|
|
required this.inviteeEmail,
|
|
this.status = 'pending',
|
|
required this.createdAt,
|
|
this.respondedAt,
|
|
});
|
|
|
|
/// Crée une invitation à partir d'un document Firestore.
|
|
///
|
|
/// Gère les formats `Timestamp`, `int` et `DateTime` pour les dates.
|
|
factory TripInvitation.fromFirestore(
|
|
DocumentSnapshot<Map<String, dynamic>> doc,
|
|
) {
|
|
final data = doc.data() ?? <String, dynamic>{};
|
|
|
|
return TripInvitation(
|
|
id: doc.id,
|
|
tripId: data['tripId'] as String? ?? '',
|
|
tripTitle: data['tripTitle'] as String? ?? '',
|
|
inviterId: data['inviterId'] as String? ?? '',
|
|
inviterName: data['inviterName'] as String? ?? 'Quelqu\'un',
|
|
inviteeId: data['inviteeId'] as String? ?? '',
|
|
inviteeEmail: data['inviteeEmail'] as String? ?? '',
|
|
status: data['status'] as String? ?? 'pending',
|
|
createdAt: _parseDate(data['createdAt']) ?? DateTime.now(),
|
|
respondedAt: _parseDate(data['respondedAt']),
|
|
);
|
|
}
|
|
|
|
/// Convertit l'invitation en map Firestore.
|
|
///
|
|
/// [respondedAt] est omis si null pour éviter d'écraser inutilement la donnée.
|
|
Map<String, dynamic> toMap() {
|
|
final map = <String, dynamic>{
|
|
'tripId': tripId,
|
|
'tripTitle': tripTitle,
|
|
'inviterId': inviterId,
|
|
'inviterName': inviterName,
|
|
'inviteeId': inviteeId,
|
|
'inviteeEmail': inviteeEmail,
|
|
'status': status,
|
|
'createdAt': Timestamp.fromDate(createdAt),
|
|
};
|
|
|
|
if (respondedAt != null) {
|
|
map['respondedAt'] = Timestamp.fromDate(respondedAt!);
|
|
}
|
|
|
|
return map;
|
|
}
|
|
|
|
/// Retourne une copie avec les champs fournis.
|
|
///
|
|
/// Utile pour mettre à jour un statut localement sans muter l'instance initiale.
|
|
TripInvitation copyWith({
|
|
String? id,
|
|
String? tripId,
|
|
String? tripTitle,
|
|
String? inviterId,
|
|
String? inviterName,
|
|
String? inviteeId,
|
|
String? inviteeEmail,
|
|
String? status,
|
|
DateTime? createdAt,
|
|
DateTime? respondedAt,
|
|
}) {
|
|
return TripInvitation(
|
|
id: id ?? this.id,
|
|
tripId: tripId ?? this.tripId,
|
|
tripTitle: tripTitle ?? this.tripTitle,
|
|
inviterId: inviterId ?? this.inviterId,
|
|
inviterName: inviterName ?? this.inviterName,
|
|
inviteeId: inviteeId ?? this.inviteeId,
|
|
inviteeEmail: inviteeEmail ?? this.inviteeEmail,
|
|
status: status ?? this.status,
|
|
createdAt: createdAt ?? this.createdAt,
|
|
respondedAt: respondedAt ?? this.respondedAt,
|
|
);
|
|
}
|
|
|
|
/// Convertit une valeur de date Firestore vers [DateTime].
|
|
///
|
|
/// Retourne `null` si la valeur est absente ou non reconnue.
|
|
static DateTime? _parseDate(dynamic value) {
|
|
if (value == null) {
|
|
return null;
|
|
}
|
|
if (value is Timestamp) {
|
|
return value.toDate();
|
|
}
|
|
if (value is int) {
|
|
return DateTime.fromMillisecondsSinceEpoch(value);
|
|
}
|
|
if (value is DateTime) {
|
|
return value;
|
|
}
|
|
return null;
|
|
}
|
|
}
|