Files
TravelMate/lib/blocs/activity/activity_state.dart

233 lines
5.9 KiB
Dart

import 'package:equatable/equatable.dart';
import '../../models/activity.dart';
/// Base class for all activity-related states
abstract class ActivityState extends Equatable {
const ActivityState();
@override
List<Object?> get props => [];
}
/// Initial state when no activities have been loaded
class ActivityInitial extends ActivityState {
const ActivityInitial();
}
/// State when activities are being loaded
class ActivityLoading extends ActivityState {
const ActivityLoading();
}
/// State when activities are being searched
class ActivitySearching extends ActivityState {
const ActivitySearching();
}
/// State when activities have been loaded successfully
class ActivityLoaded extends ActivityState {
final List<Activity> activities;
final List<Activity> filteredActivities;
final String? activeFilter;
final double? minRating;
final bool showVotedOnly;
const ActivityLoaded({
required this.activities,
required this.filteredActivities,
this.activeFilter,
this.minRating,
this.showVotedOnly = false,
});
@override
List<Object?> get props => [
activities,
filteredActivities,
activeFilter,
minRating,
showVotedOnly,
];
/// Creates a copy of the current state with optional modifications
ActivityLoaded copyWith({
List<Activity>? activities,
List<Activity>? filteredActivities,
String? activeFilter,
double? minRating,
bool? showVotedOnly,
}) {
return ActivityLoaded(
activities: activities ?? this.activities,
filteredActivities: filteredActivities ?? this.filteredActivities,
activeFilter: activeFilter ?? this.activeFilter,
minRating: minRating ?? this.minRating,
showVotedOnly: showVotedOnly ?? this.showVotedOnly,
);
}
/// Gets activities by category
List<Activity> getActivitiesByCategory(String category) {
return activities
.where((activity) => activity.category == category)
.toList();
}
/// Gets top rated activities
List<Activity> getTopRatedActivities({int limit = 10}) {
final sorted = List<Activity>.from(activities);
sorted.sort((a, b) {
final aScore = a.totalVotes;
final bScore = b.totalVotes;
if (aScore != bScore) {
return bScore.compareTo(aScore);
}
return (b.rating ?? 0).compareTo(a.rating ?? 0);
});
return sorted.take(limit).toList();
}
}
/// State when search results are available
class ActivitySearchResults extends ActivityState {
final List<Activity> searchResults;
final String query;
final bool isLoading;
final Activity? newlyAddedActivity;
const ActivitySearchResults({
required this.searchResults,
required this.query,
this.isLoading = false,
this.newlyAddedActivity,
});
@override
List<Object?> get props => [
searchResults,
query,
isLoading,
newlyAddedActivity,
];
/// Creates a copy with optional modifications
ActivitySearchResults copyWith({
List<Activity>? searchResults,
String? query,
bool? isLoading,
Activity? newlyAddedActivity,
}) {
return ActivitySearchResults(
searchResults: searchResults ?? this.searchResults,
query: query ?? this.query,
isLoading: isLoading ?? this.isLoading,
newlyAddedActivity: newlyAddedActivity ?? this.newlyAddedActivity,
);
}
}
/// State when an operation has completed successfully
class ActivityOperationSuccess extends ActivityState {
final String message;
final String? operationType;
const ActivityOperationSuccess(this.message, {this.operationType});
@override
List<Object?> get props => [message, operationType];
}
/// State when an error has occurred
class ActivityError extends ActivityState {
final String message;
final String? errorCode;
final dynamic error;
const ActivityError(this.message, {this.errorCode, this.error});
@override
List<Object?> get props => [message, errorCode, error];
}
/// State when voting is in progress
class ActivityVoting extends ActivityState {
final String activityId;
final List<Activity> activities;
const ActivityVoting({required this.activityId, required this.activities});
@override
List<Object> get props => [activityId, activities];
}
/// State when activity is being updated
class ActivityUpdating extends ActivityState {
final String activityId;
final List<Activity> activities;
const ActivityUpdating({required this.activityId, required this.activities});
@override
List<Object> get props => [activityId, activities];
}
/// State when activities are being added in batch
class ActivityBatchAdding extends ActivityState {
final List<Activity> activitiesToAdd;
final int progress;
final int total;
const ActivityBatchAdding({
required this.activitiesToAdd,
required this.progress,
required this.total,
});
@override
List<Object> get props => [activitiesToAdd, progress, total];
/// Gets the progress as a percentage
double get progressPercentage => total > 0 ? progress / total : 0.0;
}
/// State when an activity has been successfully added
class ActivityAdded extends ActivityState {
final Activity activity;
final String message;
const ActivityAdded({required this.activity, required this.message});
@override
List<Object> get props => [activity, message];
}
/// State when an activity has been successfully deleted
class ActivityDeleted extends ActivityState {
final String activityId;
final String message;
const ActivityDeleted({required this.activityId, required this.message});
@override
List<Object> get props => [activityId, message];
}
/// State when vote has been successfully recorded
class ActivityVoteRecorded extends ActivityState {
final String activityId;
final int vote;
final String userId;
const ActivityVoteRecorded({
required this.activityId,
required this.vote,
required this.userId,
});
@override
List<Object> get props => [activityId, vote, userId];
}