233 lines
5.9 KiB
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];
|
|
}
|