Enhance model and service documentation with detailed comments and descriptions
- Updated Group, Trip, User, and other model classes to include comprehensive documentation for better understanding and maintainability. - Improved error handling and logging in services, including AuthService, ErrorService, and StorageService. - Added validation and business logic explanations in ExpenseService and TripService. - Refactored method comments to follow a consistent format across the codebase. - Translated error messages and comments from French to English for consistency.
This commit is contained in:
@@ -1,3 +1,40 @@
|
||||
/// A BLoC (Business Logic Component) that manages trip-related operations.
|
||||
///
|
||||
/// This bloc handles all trip operations including creation, updates, deletion,
|
||||
/// and loading trips for users. It provides real-time updates through streams
|
||||
/// and manages the trip lifecycle with proper state transitions.
|
||||
///
|
||||
/// The bloc processes these main events:
|
||||
/// - [LoadTripsByUserId]: Loads all trips for a specific user with real-time updates
|
||||
/// - [TripCreateRequested]: Creates a new trip and reloads the user's trip list
|
||||
/// - [TripUpdateRequested]: Updates an existing trip and refreshes the list
|
||||
/// - [TripDeleteRequested]: Deletes a trip and refreshes the list
|
||||
/// - [ResetTrips]: Resets the trip state and cancels subscriptions
|
||||
///
|
||||
/// Dependencies:
|
||||
/// - [TripRepository]: Repository for trip data operations
|
||||
///
|
||||
/// State Management:
|
||||
/// The bloc maintains the current user ID to enable automatic list refreshing
|
||||
/// after operations like create, update, or delete. This ensures the UI stays
|
||||
/// in sync with the latest data.
|
||||
///
|
||||
/// Example usage:
|
||||
/// ```dart
|
||||
/// final tripBloc = TripBloc(tripRepository);
|
||||
///
|
||||
/// // Load trips for a user
|
||||
/// tripBloc.add(LoadTripsByUserId(userId: 'userId123'));
|
||||
///
|
||||
/// // Create a new trip
|
||||
/// tripBloc.add(TripCreateRequested(trip: newTrip));
|
||||
///
|
||||
/// // Update a trip
|
||||
/// tripBloc.add(TripUpdateRequested(trip: updatedTrip));
|
||||
///
|
||||
/// // Delete a trip
|
||||
/// tripBloc.add(TripDeleteRequested(tripId: 'tripId456'));
|
||||
/// ```
|
||||
import 'dart:async';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:travel_mate/models/trip.dart';
|
||||
@@ -5,12 +42,24 @@ import 'trip_event.dart';
|
||||
import 'trip_state.dart';
|
||||
import '../../repositories/trip_repository.dart';
|
||||
|
||||
|
||||
/// BLoC that manages trip-related operations and state.
|
||||
class TripBloc extends Bloc<TripEvent, TripState> {
|
||||
/// Repository for trip data operations
|
||||
final TripRepository _repository;
|
||||
|
||||
/// Subscription to trip stream for real-time updates
|
||||
StreamSubscription? _tripsSubscription;
|
||||
|
||||
/// Current user ID for automatic list refreshing after operations
|
||||
String? _currentUserId;
|
||||
|
||||
/// Constructor for TripBloc.
|
||||
///
|
||||
/// Initializes the bloc with the trip repository and sets up event handlers
|
||||
/// for all trip-related operations.
|
||||
///
|
||||
/// Args:
|
||||
/// [_repository]: Repository for trip data operations
|
||||
TripBloc(this._repository) : super(TripInitial()) {
|
||||
on<LoadTripsByUserId>(_onLoadTripsByUserId);
|
||||
on<TripCreateRequested>(_onTripCreateRequested);
|
||||
@@ -20,6 +69,15 @@ class TripBloc extends Bloc<TripEvent, TripState> {
|
||||
on<ResetTrips>(_onResetTrips);
|
||||
}
|
||||
|
||||
/// Handles [LoadTripsByUserId] events.
|
||||
///
|
||||
/// Loads all trips for a specific user with real-time updates via stream subscription.
|
||||
/// Stores the user ID for future automatic refreshing after operations and cancels
|
||||
/// any existing subscription to prevent memory leaks.
|
||||
///
|
||||
/// Args:
|
||||
/// [event]: The LoadTripsByUserId event containing the user ID
|
||||
/// [emit]: State emitter function
|
||||
Future<void> _onLoadTripsByUserId(
|
||||
LoadTripsByUserId event,
|
||||
Emitter<TripState> emit,
|
||||
@@ -39,6 +97,14 @@ class TripBloc extends Bloc<TripEvent, TripState> {
|
||||
);
|
||||
}
|
||||
|
||||
/// Handles [_TripsUpdated] events.
|
||||
///
|
||||
/// Processes real-time updates from the trip stream and emits the
|
||||
/// updated trip list to the UI.
|
||||
///
|
||||
/// Args:
|
||||
/// [event]: The _TripsUpdated event containing the updated trip list
|
||||
/// [emit]: State emitter function
|
||||
void _onTripsUpdated(
|
||||
_TripsUpdated event,
|
||||
Emitter<TripState> emit,
|
||||
@@ -46,6 +112,15 @@ class TripBloc extends Bloc<TripEvent, TripState> {
|
||||
emit(TripLoaded(event.trips));
|
||||
}
|
||||
|
||||
/// Handles [TripCreateRequested] events.
|
||||
///
|
||||
/// Creates a new trip and automatically refreshes the user's trip list
|
||||
/// to show the newly created trip. Includes a delay to allow the creation
|
||||
/// to complete before refreshing.
|
||||
///
|
||||
/// Args:
|
||||
/// [event]: The TripCreateRequested event containing the trip data
|
||||
/// [emit]: State emitter function
|
||||
Future<void> _onTripCreateRequested(
|
||||
TripCreateRequested event,
|
||||
Emitter<TripState> emit,
|
||||
@@ -63,27 +138,45 @@ class TripBloc extends Bloc<TripEvent, TripState> {
|
||||
}
|
||||
|
||||
} catch (e) {
|
||||
emit(TripError('Erreur lors de la création: $e'));
|
||||
emit(TripError('Error during creation: $e'));
|
||||
}
|
||||
}
|
||||
|
||||
/// Handles [TripUpdateRequested] events.
|
||||
///
|
||||
/// Updates an existing trip and automatically refreshes the user's trip list
|
||||
/// to show the updated information. Includes a delay to allow the update
|
||||
/// to complete before refreshing.
|
||||
///
|
||||
/// Args:
|
||||
/// [event]: The TripUpdateRequested event containing the updated trip data
|
||||
/// [emit]: State emitter function
|
||||
Future<void> _onTripUpdateRequested(
|
||||
TripUpdateRequested event,
|
||||
Emitter<TripState> emit,
|
||||
) async {
|
||||
try {
|
||||
await _repository.updateTrip(event.trip.id!, event.trip);
|
||||
emit(const TripOperationSuccess('Voyage mis à jour avec succès'));
|
||||
emit(const TripOperationSuccess('Trip updated successfully'));
|
||||
await Future.delayed(const Duration(milliseconds: 500));
|
||||
if (_currentUserId != null) {
|
||||
add(LoadTripsByUserId(userId: _currentUserId!));
|
||||
}
|
||||
|
||||
} catch (e) {
|
||||
emit(TripError('Erreur lors de la mise à jour: $e'));
|
||||
emit(TripError('Error during update: $e'));
|
||||
}
|
||||
}
|
||||
|
||||
/// Handles [TripDeleteRequested] events.
|
||||
///
|
||||
/// Deletes a trip and automatically refreshes the user's trip list
|
||||
/// to remove the deleted trip from the UI. Includes a delay to allow
|
||||
/// the deletion to complete before refreshing.
|
||||
///
|
||||
/// Args:
|
||||
/// [event]: The TripDeleteRequested event containing the trip ID to delete
|
||||
/// [emit]: State emitter function
|
||||
Future<void> _onTripDeleteRequested(
|
||||
TripDeleteRequested event,
|
||||
Emitter<TripState> emit,
|
||||
@@ -91,7 +184,7 @@ class TripBloc extends Bloc<TripEvent, TripState> {
|
||||
try {
|
||||
await _repository.deleteTrip(event.tripId);
|
||||
|
||||
emit(const TripOperationSuccess('Voyage supprimé avec succès'));
|
||||
emit(const TripOperationSuccess('Trip deleted successfully'));
|
||||
|
||||
await Future.delayed(const Duration(milliseconds: 500));
|
||||
if (_currentUserId != null) {
|
||||
@@ -99,10 +192,19 @@ class TripBloc extends Bloc<TripEvent, TripState> {
|
||||
}
|
||||
|
||||
} catch (e) {
|
||||
emit(TripError('Erreur lors de la suppression: $e'));
|
||||
emit(TripError('Error during deletion: $e'));
|
||||
}
|
||||
}
|
||||
|
||||
/// Handles [ResetTrips] events.
|
||||
///
|
||||
/// Resets the trip state to initial and cleans up resources.
|
||||
/// Cancels the trip stream subscription and clears the current user ID.
|
||||
/// This is useful for user logout or when switching contexts.
|
||||
///
|
||||
/// Args:
|
||||
/// [event]: The ResetTrips event
|
||||
/// [emit]: State emitter function
|
||||
Future<void> _onResetTrips(
|
||||
ResetTrips event,
|
||||
Emitter<TripState> emit,
|
||||
@@ -112,6 +214,10 @@ class TripBloc extends Bloc<TripEvent, TripState> {
|
||||
emit(TripInitial());
|
||||
}
|
||||
|
||||
/// Cleans up resources when the bloc is closed.
|
||||
///
|
||||
/// Cancels the trip stream subscription to prevent memory leaks
|
||||
/// and ensure proper disposal of resources.
|
||||
@override
|
||||
Future<void> close() {
|
||||
_tripsSubscription?.cancel();
|
||||
@@ -119,9 +225,18 @@ class TripBloc extends Bloc<TripEvent, TripState> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Private event for handling real-time trip updates from streams.
|
||||
///
|
||||
/// This internal event is used to process updates from the trip stream
|
||||
/// subscription and emit appropriate states based on the received data.
|
||||
class _TripsUpdated extends TripEvent {
|
||||
/// List of trips received from the stream
|
||||
final List<Trip> trips;
|
||||
|
||||
/// Creates a _TripsUpdated event.
|
||||
///
|
||||
/// Args:
|
||||
/// [trips]: List of trips from the stream update
|
||||
const _TripsUpdated(this.trips);
|
||||
|
||||
@override
|
||||
|
||||
@@ -1,6 +1,26 @@
|
||||
/// Events for trip-related operations in the TripBloc.
|
||||
///
|
||||
/// This file defines all possible events that can be dispatched to the TripBloc
|
||||
/// to trigger trip-related state changes and operations such as loading trips,
|
||||
/// creating trips, updating trip information, and performing CRUD operations.
|
||||
///
|
||||
/// Event Categories:
|
||||
/// - **Loading Events**: LoadTripsByUserId
|
||||
/// - **CRUD Operations**: TripCreateRequested, TripUpdateRequested, TripDeleteRequested
|
||||
/// - **State Management**: ResetTrips
|
||||
///
|
||||
/// The events support complete trip lifecycle management with automatic
|
||||
/// list refreshing after operations to maintain UI consistency.
|
||||
///
|
||||
/// All events extend [TripEvent] and implement [Equatable] for proper
|
||||
/// equality comparison in the BLoC pattern.
|
||||
import 'package:equatable/equatable.dart';
|
||||
import '../../models/trip.dart';
|
||||
|
||||
/// Base class for all trip-related events.
|
||||
///
|
||||
/// All trip events must extend this class and implement the [props] getter
|
||||
/// for proper equality comparison in the BLoC pattern.
|
||||
abstract class TripEvent extends Equatable {
|
||||
const TripEvent();
|
||||
|
||||
@@ -8,40 +28,98 @@ abstract class TripEvent extends Equatable {
|
||||
List<Object?> get props => [];
|
||||
}
|
||||
|
||||
/// Event to load all trips associated with a specific user.
|
||||
///
|
||||
/// This event retrieves all trips where the user is a participant or organizer,
|
||||
/// providing a comprehensive view of the user's travel activities. The loading
|
||||
/// uses real-time streams to keep the trip list updated automatically.
|
||||
///
|
||||
/// Args:
|
||||
/// [userId]: The unique identifier of the user whose trips should be loaded
|
||||
class LoadTripsByUserId extends TripEvent {
|
||||
/// The unique identifier of the user
|
||||
final String userId;
|
||||
|
||||
/// Creates a LoadTripsByUserId event.
|
||||
///
|
||||
/// Args:
|
||||
/// [userId]: The user ID to load trips for
|
||||
const LoadTripsByUserId({required this.userId});
|
||||
|
||||
@override
|
||||
List<Object?> get props => [userId];
|
||||
}
|
||||
|
||||
/// Event to request creation of a new trip.
|
||||
///
|
||||
/// This event creates a new trip with the provided information and automatically
|
||||
/// refreshes the user's trip list to show the newly created trip. The operation
|
||||
/// includes validation and proper error handling.
|
||||
///
|
||||
/// Args:
|
||||
/// [trip]: The trip object containing all the trip information to create
|
||||
class TripCreateRequested extends TripEvent {
|
||||
/// The trip object to create
|
||||
final Trip trip;
|
||||
|
||||
/// Creates a TripCreateRequested event.
|
||||
///
|
||||
/// Args:
|
||||
/// [trip]: The trip object to create
|
||||
const TripCreateRequested({required this.trip});
|
||||
|
||||
@override
|
||||
List<Object?> get props => [trip];
|
||||
}
|
||||
|
||||
/// Event to request updating an existing trip.
|
||||
///
|
||||
/// This event updates an existing trip with new information and automatically
|
||||
/// refreshes the user's trip list to reflect the changes. The trip must have
|
||||
/// a valid ID for the update operation to succeed.
|
||||
///
|
||||
/// Args:
|
||||
/// [trip]: The trip object with updated information (must include valid ID)
|
||||
class TripUpdateRequested extends TripEvent {
|
||||
/// The trip object with updated information
|
||||
final Trip trip;
|
||||
|
||||
/// Creates a TripUpdateRequested event.
|
||||
///
|
||||
/// Args:
|
||||
/// [trip]: The updated trip object (must have valid ID)
|
||||
const TripUpdateRequested({required this.trip});
|
||||
|
||||
@override
|
||||
List<Object?> get props => [trip];
|
||||
}
|
||||
|
||||
/// Event to reset the trip state and clean up resources.
|
||||
///
|
||||
/// This event resets the TripBloc to its initial state, cancels any active
|
||||
/// stream subscriptions, and clears the current user context. This is typically
|
||||
/// used during user logout or when switching between different user contexts.
|
||||
class ResetTrips extends TripEvent {
|
||||
/// Creates a ResetTrips event.
|
||||
const ResetTrips();
|
||||
}
|
||||
|
||||
/// Event to request deletion of a trip.
|
||||
///
|
||||
/// This event permanently deletes a trip and all associated data including
|
||||
/// groups, expenses, and messages. This is a destructive operation that cannot
|
||||
/// be undone. The user's trip list is automatically refreshed after deletion.
|
||||
///
|
||||
/// Args:
|
||||
/// [tripId]: The unique identifier of the trip to delete
|
||||
class TripDeleteRequested extends TripEvent {
|
||||
/// The unique identifier of the trip to delete
|
||||
final String tripId;
|
||||
|
||||
/// Creates a TripDeleteRequested event.
|
||||
///
|
||||
/// Args:
|
||||
/// [tripId]: The ID of the trip to delete
|
||||
const TripDeleteRequested({required this.tripId});
|
||||
|
||||
@override
|
||||
|
||||
@@ -1,6 +1,27 @@
|
||||
/// States for trip-related operations in the TripBloc.
|
||||
///
|
||||
/// This file defines all possible states that the TripBloc can emit in response
|
||||
/// to trip-related events. The states represent different phases of trip
|
||||
/// operations including loading, success, error, and data states for trip management.
|
||||
///
|
||||
/// State Categories:
|
||||
/// - **Initial State**: TripInitial
|
||||
/// - **Loading States**: TripLoading
|
||||
/// - **Success States**: TripLoaded, TripCreated, TripOperationSuccess
|
||||
/// - **Error States**: TripError
|
||||
///
|
||||
/// The states support complete trip lifecycle management with proper feedback
|
||||
/// for create, read, update, and delete operations.
|
||||
///
|
||||
/// All states extend [TripState] and implement [Equatable] for proper
|
||||
/// equality comparison and state change detection in the BLoC pattern.
|
||||
import 'package:equatable/equatable.dart';
|
||||
import '../../models/trip.dart';
|
||||
|
||||
/// Base class for all trip-related states.
|
||||
///
|
||||
/// All trip states must extend this class and implement the [props] getter
|
||||
/// for proper equality comparison in the BLoC pattern.
|
||||
abstract class TripState extends Equatable {
|
||||
const TripState();
|
||||
|
||||
@@ -8,44 +29,111 @@ abstract class TripState extends Equatable {
|
||||
List<Object?> get props => [];
|
||||
}
|
||||
|
||||
/// The initial state of the TripBloc before any operations are performed.
|
||||
///
|
||||
/// This is the default state when the bloc is first created and represents
|
||||
/// a clean slate with no trip data loaded or operations in progress.
|
||||
class TripInitial extends TripState {}
|
||||
|
||||
/// State indicating that a trip operation is currently in progress.
|
||||
///
|
||||
/// This state is emitted when the bloc is performing operations like
|
||||
/// loading trips, creating trips, updating trip information, or deleting trips.
|
||||
/// UI components can use this state to show loading indicators.
|
||||
class TripLoading extends TripState {}
|
||||
|
||||
/// State containing a list of successfully loaded trips.
|
||||
///
|
||||
/// This state is emitted when trips have been successfully retrieved
|
||||
/// from the repository, either through initial loading or real-time updates.
|
||||
/// The UI can use this data to display the list of available trips for the user.
|
||||
///
|
||||
/// Properties:
|
||||
/// [trips]: List of Trip objects that were loaded
|
||||
class TripLoaded extends TripState {
|
||||
/// The list of loaded trips
|
||||
final List<Trip> trips;
|
||||
|
||||
/// Creates a TripLoaded state.
|
||||
///
|
||||
/// Args:
|
||||
/// [trips]: The list of trips to include in this state
|
||||
const TripLoaded(this.trips);
|
||||
|
||||
@override
|
||||
List<Object?> get props => [trips];
|
||||
}
|
||||
|
||||
/// State indicating successful trip creation.
|
||||
///
|
||||
/// This state is emitted when a new trip has been successfully created.
|
||||
/// It contains the ID of the newly created trip and a success message
|
||||
/// that can be displayed to the user. This state is typically followed
|
||||
/// by automatic reloading of the user's trip list.
|
||||
///
|
||||
/// Properties:
|
||||
/// [tripId]: The unique identifier of the newly created trip
|
||||
/// [message]: A success message to display to the user
|
||||
class TripCreated extends TripState {
|
||||
/// The unique identifier of the newly created trip
|
||||
final String tripId;
|
||||
|
||||
/// Success message for the user
|
||||
final String message;
|
||||
|
||||
/// Creates a TripCreated state.
|
||||
///
|
||||
/// Args:
|
||||
/// [tripId]: The ID of the newly created trip
|
||||
/// [message]: Optional success message (defaults to "Trip created successfully")
|
||||
const TripCreated({
|
||||
required this.tripId,
|
||||
this.message = 'Voyage créé avec succès',
|
||||
this.message = 'Trip created successfully',
|
||||
});
|
||||
|
||||
@override
|
||||
List<Object?> get props => [tripId, message];
|
||||
}
|
||||
|
||||
/// State indicating successful completion of a trip operation.
|
||||
///
|
||||
/// This state is emitted when operations like updating or deleting trips
|
||||
/// have completed successfully. It contains a message that can be displayed
|
||||
/// to inform the user of the successful operation. This state is typically
|
||||
/// followed by automatic reloading of the user's trip list.
|
||||
///
|
||||
/// Properties:
|
||||
/// [message]: A success message describing the completed operation
|
||||
class TripOperationSuccess extends TripState {
|
||||
/// The success message to display to the user
|
||||
final String message;
|
||||
|
||||
/// Creates a TripOperationSuccess state.
|
||||
///
|
||||
/// Args:
|
||||
/// [message]: The success message to display
|
||||
const TripOperationSuccess(this.message);
|
||||
|
||||
@override
|
||||
List<Object?> get props => [message];
|
||||
}
|
||||
|
||||
/// State indicating that a trip operation has failed.
|
||||
///
|
||||
/// This state is emitted when any trip operation encounters an error.
|
||||
/// It contains an error message that can be displayed to the user to
|
||||
/// explain what went wrong during the operation.
|
||||
///
|
||||
/// Properties:
|
||||
/// [message]: An error message describing what went wrong
|
||||
class TripError extends TripState {
|
||||
/// The error message to display to the user
|
||||
final String message;
|
||||
|
||||
/// Creates a TripError state.
|
||||
///
|
||||
/// Args:
|
||||
/// [message]: The error message to display
|
||||
const TripError(this.message);
|
||||
|
||||
@override
|
||||
|
||||
Reference in New Issue
Block a user