Line data Source code
1 : import 'package:flutter/foundation.dart'; 2 : import '../../domain/entities/models/mdl_the_movie.dart'; 3 : import '../../domain/repositories/repository_api_conn.dart'; 4 : 5 : /// Manages the state and logic for popular movies and search results. 6 : /// 7 : /// The `MoviesProvider` is responsible for: 8 : /// - Fetching and storing popular movies from the API. 9 : /// - Searching movies by query and managing search results. 10 : /// - Handling loading, error, and empty states for both popular and search movies. 11 : /// - Providing methods to refresh, reset, and access movies by ID. 12 : /// - Notifying listeners to enable reactive UI updates. 13 : /// 14 : /// ### State 15 : /// - `_popularMovies`: Internal list of popular movies. 16 : /// - `_isLoadingPopular`: Indicates if popular movies are being loaded. 17 : /// - `_popularError`: Stores error messages for popular movies. 18 : /// - `_searchResults`: Internal list of search results. 19 : /// - `_isLoadingSearch`: Indicates if search results are being loaded. 20 : /// - `_searchError`: Stores error messages for search. 21 : /// - `_searchQuery`: Current search query string. 22 : /// 23 : /// ### Getters 24 : /// - `popularMovies`: List of popular movies. 25 : /// - `isLoadingPopular`: Loading state for popular movies. 26 : /// - `popularError`: Error message for popular movies. 27 : /// - `searchResults`: List of search results. 28 : /// - `isLoadingSearch`: Loading state for search. 29 : /// - `searchError`: Error message for search. 30 : /// - `searchQuery`: Current search query. 31 : /// - `hasPopularMovies`: Whether there are popular movies loaded. 32 : /// - `hasSearchResults`: Whether there are search results loaded. 33 : /// 34 : /// ### Methods 35 : /// - [fetchPopularMovies]: Loads popular movies from the API. 36 : /// - [searchMovies]: Searches movies by query. 37 : /// - [clearSearch]: Clears search results and state. 38 : /// - [refreshPopularMovies]: Reloads popular movies. 39 : /// - [getMovieById]: Retrieves a movie by its ID from either list. 40 : /// - [reset]: Resets all movie-related state. 41 : /// 42 : /// ### Usage 43 : /// Use this provider to manage and reactively update movie data in your app, including popular and search results. 44 : class MoviesProvider with ChangeNotifier { 45 1 : MoviesProvider(this._apiRepository); 46 : 47 : final ApiConnRepository _apiRepository; 48 : 49 : // Popular Movies State 50 : List<TheMovie> _popularMovies = []; 51 : bool _isLoadingPopular = false; 52 : String? _popularError; 53 : 54 : // Search Movies State 55 : List<TheMovie> _searchResults = []; 56 : bool _isLoadingSearch = false; 57 : String? _searchError; 58 : String _searchQuery = ''; 59 : 60 : // Getters for Popular Movies 61 2 : List<TheMovie> get popularMovies => _popularMovies; 62 2 : bool get isLoadingPopular => _isLoadingPopular; 63 2 : String? get popularError => _popularError; 64 : 65 : // Getters for Search 66 2 : List<TheMovie> get searchResults => _searchResults; 67 2 : bool get isLoadingSearch => _isLoadingSearch; 68 2 : String? get searchError => _searchError; 69 2 : String get searchQuery => _searchQuery; 70 : 71 : /// Fetch popular movies 72 : /// 73 : /// **Description:** 74 : /// - Makes a request to the API to fetch popular movies. 75 : /// - Updates the state with the results or an error in case of failure. 76 : /// 77 : /// **Errors:** 78 : /// - Sets an error message in `_popularError` if a problem occurs. 79 1 : Future<void> fetchPopularMovies() async { 80 1 : _isLoadingPopular = true; 81 1 : _popularError = null; 82 1 : notifyListeners(); 83 : 84 : try { 85 2 : final result = await _apiRepository.getPopularMovies(); 86 2 : _popularMovies = result.results; 87 1 : _isLoadingPopular = false; 88 1 : notifyListeners(); 89 : } catch (e) { 90 1 : _isLoadingPopular = false; 91 3 : _popularError = 'Error loading popular movies: ${e.toString()}'; 92 1 : notifyListeners(); 93 : } 94 : } 95 : 96 : /// Search movies by query 97 : /// 98 : /// **Parameters:** 99 : /// - `query` (String): The search term to query movies. 100 : /// 101 : /// **Description:** 102 : /// - Makes a request to the API to search for movies matching the query. 103 : /// - Updates the state with the results or an error in case of failure. 104 : /// 105 : /// **Errors:** 106 : /// - Sets an error message in `_searchError` if a problem occurs. 107 1 : Future<void> searchMovies(String query) async { 108 2 : if (query.trim().isEmpty) { 109 1 : _clearSearchResults(); 110 : return; 111 : } 112 : 113 1 : _searchQuery = query; 114 1 : _isLoadingSearch = true; 115 1 : _searchError = null; 116 1 : notifyListeners(); 117 : 118 : try { 119 2 : final result = await _apiRepository.getSearchMovies(query); 120 2 : _searchResults = result.results; 121 1 : _isLoadingSearch = false; 122 1 : notifyListeners(); 123 : } catch (e) { 124 1 : _isLoadingSearch = false; 125 3 : _searchError = 'Error searching movies: ${e.toString()}'; 126 1 : notifyListeners(); 127 : } 128 : } 129 : 130 : /// Clears the search results. 131 : /// 132 : /// **Description:** 133 : /// - Resets the search results and related state. 134 1 : void _clearSearchResults() { 135 2 : _searchResults = []; 136 1 : _searchQuery = ''; 137 1 : _searchError = null; 138 1 : notifyListeners(); 139 : } 140 : 141 : /// Clears the current search. 142 : /// 143 : /// **Description:** 144 : /// - Calls `_clearSearchResults` to reset the search state. 145 1 : void clearSearch() { 146 1 : _clearSearchResults(); 147 : } 148 : 149 : /// Refreshes the popular movies. 150 : /// 151 : /// **Description:** 152 : /// - Calls `fetchPopularMovies` to update the popular movies. 153 1 : Future<void> refreshPopularMovies() async { 154 1 : await fetchPopularMovies(); 155 : } 156 : 157 : /// Gets a movie by its ID. 158 : /// 159 : /// **Parameters:** 160 : /// - `id` (int): The ID of the movie to search for. 161 : /// 162 : /// **Description:** 163 : /// - Searches for the movie in the popular list or in the search results. 164 : /// - Returns `null` if not found. 165 1 : TheMovie? getMovieById(int id) { 166 : // Try to find in popular movies first 167 : try { 168 5 : return _popularMovies.firstWhere((movie) => movie.id == id); 169 : } catch (e) { 170 : // If not found in popular, try in search results 171 : try { 172 5 : return _searchResults.firstWhere((movie) => movie.id == id); 173 : } catch (e) { 174 : return null; 175 : } 176 : } 177 : } 178 : 179 : /// Checks if there are any loaded movies. 180 : /// 181 : /// **Description:** 182 : /// - Checks if there are any popular movies or search results available. 183 3 : bool get hasPopularMovies => _popularMovies.isNotEmpty; 184 3 : bool get hasSearchResults => _searchResults.isNotEmpty; 185 : 186 : /// Resets the entire state. 187 : /// 188 : /// **Description:** 189 : /// - Resets all the lists and states related to movies. 190 1 : void reset() { 191 2 : _popularMovies = []; 192 1 : _isLoadingPopular = false; 193 1 : _popularError = null; 194 2 : _searchResults = []; 195 1 : _isLoadingSearch = false; 196 1 : _searchError = null; 197 1 : _searchQuery = ''; 198 1 : notifyListeners(); 199 : } 200 : }