| 
									
										
											![factory-droid[bot]](/assets/img/avatar_default.png)  
											
												feat: Add TorrentEngine library and new API client
- Created complete TorrentEngine library module with LibTorrent4j
  - Full torrent management (add, pause, resume, remove)
  - Magnet link metadata extraction
  - File priority management (even during download)
  - Foreground service with persistent notification
  - Room database for state persistence
  - Reactive Flow API for UI updates
- Integrated TorrentEngine with MainActivity via MethodChannel
  - addTorrent, getTorrents, pauseTorrent, resumeTorrent, removeTorrent
  - setFilePriority for dynamic file selection
  - Full JSON serialization for Flutter communication
- Created new NeoMoviesApiClient for Go-based backend
  - Email verification flow (register, verify, resendCode)
  - Google OAuth support
  - Torrent search via RedAPI
  - Multiple player support (Alloha, Lumex, Vibix)
  - Enhanced reactions system (likes/dislikes)
  - All movies/TV shows endpoints
- Updated dependencies and build configuration
  - Java 17 compatibility
  - Updated Kotlin coroutines to 1.9.0
  - Fixed build_runner version conflict
  - Added torrentengine module to settings.gradle.kts
- Added comprehensive documentation
  - TorrentEngine README with usage examples
  - DEVELOPMENT_SUMMARY with full implementation details
  - ProGuard rules for library
This is a complete rewrite of torrent functionality as a reusable library.
											
										 
											2025-10-02 10:56:22 +00:00
										 |  |  | import 'dart:convert'; | 
					
						
							|  |  |  | import 'package:flutter_dotenv/flutter_dotenv.dart'; | 
					
						
							|  |  |  | import 'package:http/http.dart' as http; | 
					
						
							|  |  |  | import 'package:neomovies_mobile/data/models/auth_response.dart'; | 
					
						
							|  |  |  | import 'package:neomovies_mobile/data/models/favorite.dart'; | 
					
						
							|  |  |  | import 'package:neomovies_mobile/data/models/movie.dart'; | 
					
						
							|  |  |  | import 'package:neomovies_mobile/data/models/reaction.dart'; | 
					
						
							|  |  |  | import 'package:neomovies_mobile/data/models/user.dart'; | 
					
						
							|  |  |  | import 'package:neomovies_mobile/data/models/torrent.dart'; | 
					
						
							| 
									
										
										
										
											2025-10-02 18:28:52 +00:00
										 |  |  | import 'package:neomovies_mobile/data/models/torrent/torrent_item.dart'; | 
					
						
							| 
									
										
											![factory-droid[bot]](/assets/img/avatar_default.png)  
											
												feat: Add TorrentEngine library and new API client
- Created complete TorrentEngine library module with LibTorrent4j
  - Full torrent management (add, pause, resume, remove)
  - Magnet link metadata extraction
  - File priority management (even during download)
  - Foreground service with persistent notification
  - Room database for state persistence
  - Reactive Flow API for UI updates
- Integrated TorrentEngine with MainActivity via MethodChannel
  - addTorrent, getTorrents, pauseTorrent, resumeTorrent, removeTorrent
  - setFilePriority for dynamic file selection
  - Full JSON serialization for Flutter communication
- Created new NeoMoviesApiClient for Go-based backend
  - Email verification flow (register, verify, resendCode)
  - Google OAuth support
  - Torrent search via RedAPI
  - Multiple player support (Alloha, Lumex, Vibix)
  - Enhanced reactions system (likes/dislikes)
  - All movies/TV shows endpoints
- Updated dependencies and build configuration
  - Java 17 compatibility
  - Updated Kotlin coroutines to 1.9.0
  - Fixed build_runner version conflict
  - Added torrentengine module to settings.gradle.kts
- Added comprehensive documentation
  - TorrentEngine README with usage examples
  - DEVELOPMENT_SUMMARY with full implementation details
  - ProGuard rules for library
This is a complete rewrite of torrent functionality as a reusable library.
											
										 
											2025-10-02 10:56:22 +00:00
										 |  |  | import 'package:neomovies_mobile/data/models/player/player_response.dart'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /// New API client for neomovies-api (Go-based backend)
 | 
					
						
							|  |  |  | /// This client provides improved performance and new features:
 | 
					
						
							|  |  |  | /// - Email verification flow
 | 
					
						
							|  |  |  | /// - Google OAuth support
 | 
					
						
							|  |  |  | /// - Torrent search via RedAPI
 | 
					
						
							|  |  |  | /// - Multiple player support (Alloha, Lumex, Vibix)
 | 
					
						
							|  |  |  | /// - Enhanced reactions system
 | 
					
						
							|  |  |  | class NeoMoviesApiClient { | 
					
						
							|  |  |  |   final http.Client _client; | 
					
						
							|  |  |  |   final String _baseUrl; | 
					
						
							|  |  |  |   final String _apiVersion = 'v1'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   NeoMoviesApiClient(this._client, {String? baseUrl}) | 
					
						
							|  |  |  |       : _baseUrl = baseUrl ?? dotenv.env['API_URL'] ?? 'https://api.neomovies.ru'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   String get apiUrl => '$_baseUrl/api/$_apiVersion'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // ============================================
 | 
					
						
							|  |  |  |   // Authentication Endpoints
 | 
					
						
							|  |  |  |   // ============================================
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /// Register a new user (sends verification code to email)
 | 
					
						
							|  |  |  |   /// Returns: {"success": true, "message": "Verification code sent"}
 | 
					
						
							|  |  |  |   Future<Map<String, dynamic>> register({ | 
					
						
							|  |  |  |     required String email, | 
					
						
							|  |  |  |     required String password, | 
					
						
							|  |  |  |     required String name, | 
					
						
							|  |  |  |   }) async { | 
					
						
							|  |  |  |     final uri = Uri.parse('$apiUrl/auth/register'); | 
					
						
							|  |  |  |     final response = await _client.post( | 
					
						
							|  |  |  |       uri, | 
					
						
							|  |  |  |       headers: {'Content-Type': 'application/json'}, | 
					
						
							|  |  |  |       body: json.encode({ | 
					
						
							|  |  |  |         'email': email, | 
					
						
							|  |  |  |         'password': password, | 
					
						
							|  |  |  |         'name': name, | 
					
						
							|  |  |  |       }), | 
					
						
							|  |  |  |     ); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (response.statusCode == 200 || response.statusCode == 201) { | 
					
						
							|  |  |  |       return json.decode(response.body); | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |       throw Exception('Registration failed: ${response.body}'); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /// Verify email with code sent during registration
 | 
					
						
							|  |  |  |   /// Returns: AuthResponse with JWT token and user info
 | 
					
						
							|  |  |  |   Future<AuthResponse> verifyEmail({ | 
					
						
							|  |  |  |     required String email, | 
					
						
							|  |  |  |     required String code, | 
					
						
							|  |  |  |   }) async { | 
					
						
							|  |  |  |     final uri = Uri.parse('$apiUrl/auth/verify'); | 
					
						
							|  |  |  |     final response = await _client.post( | 
					
						
							|  |  |  |       uri, | 
					
						
							|  |  |  |       headers: {'Content-Type': 'application/json'}, | 
					
						
							|  |  |  |       body: json.encode({ | 
					
						
							|  |  |  |         'email': email, | 
					
						
							|  |  |  |         'code': code, | 
					
						
							|  |  |  |       }), | 
					
						
							|  |  |  |     ); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (response.statusCode == 200) { | 
					
						
							|  |  |  |       return AuthResponse.fromJson(json.decode(response.body)); | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |       throw Exception('Verification failed: ${response.body}'); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /// Resend verification code to email
 | 
					
						
							|  |  |  |   Future<void> resendVerificationCode(String email) async { | 
					
						
							|  |  |  |     final uri = Uri.parse('$apiUrl/auth/resend-code'); | 
					
						
							|  |  |  |     final response = await _client.post( | 
					
						
							|  |  |  |       uri, | 
					
						
							|  |  |  |       headers: {'Content-Type': 'application/json'}, | 
					
						
							|  |  |  |       body: json.encode({'email': email}), | 
					
						
							|  |  |  |     ); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (response.statusCode != 200) { | 
					
						
							|  |  |  |       throw Exception('Failed to resend code: ${response.body}'); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /// Login with email and password
 | 
					
						
							|  |  |  |   Future<AuthResponse> login({ | 
					
						
							|  |  |  |     required String email, | 
					
						
							|  |  |  |     required String password, | 
					
						
							|  |  |  |   }) async { | 
					
						
							|  |  |  |     final uri = Uri.parse('$apiUrl/auth/login'); | 
					
						
							|  |  |  |     final response = await _client.post( | 
					
						
							|  |  |  |       uri, | 
					
						
							|  |  |  |       headers: {'Content-Type': 'application/json'}, | 
					
						
							|  |  |  |       body: json.encode({ | 
					
						
							|  |  |  |         'email': email, | 
					
						
							|  |  |  |         'password': password, | 
					
						
							|  |  |  |       }), | 
					
						
							|  |  |  |     ); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (response.statusCode == 200) { | 
					
						
							|  |  |  |       return AuthResponse.fromJson(json.decode(response.body)); | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |       throw Exception('Login failed: ${response.body}'); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /// Get Google OAuth login URL
 | 
					
						
							|  |  |  |   /// User should be redirected to this URL in a WebView
 | 
					
						
							|  |  |  |   String getGoogleOAuthUrl() { | 
					
						
							|  |  |  |     return '$apiUrl/auth/google/login'; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /// Refresh authentication token
 | 
					
						
							|  |  |  |   Future<AuthResponse> refreshToken(String refreshToken) async { | 
					
						
							|  |  |  |     final uri = Uri.parse('$apiUrl/auth/refresh'); | 
					
						
							|  |  |  |     final response = await _client.post( | 
					
						
							|  |  |  |       uri, | 
					
						
							|  |  |  |       headers: {'Content-Type': 'application/json'}, | 
					
						
							|  |  |  |       body: json.encode({'refreshToken': refreshToken}), | 
					
						
							|  |  |  |     ); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (response.statusCode == 200) { | 
					
						
							|  |  |  |       return AuthResponse.fromJson(json.decode(response.body)); | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |       throw Exception('Token refresh failed: ${response.body}'); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /// Get current user profile
 | 
					
						
							|  |  |  |   Future<User> getProfile() async { | 
					
						
							|  |  |  |     final uri = Uri.parse('$apiUrl/auth/profile'); | 
					
						
							|  |  |  |     final response = await _client.get(uri); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (response.statusCode == 200) { | 
					
						
							|  |  |  |       return User.fromJson(json.decode(response.body)); | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |       throw Exception('Failed to get profile: ${response.body}'); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /// Delete user account
 | 
					
						
							|  |  |  |   Future<void> deleteAccount() async { | 
					
						
							|  |  |  |     final uri = Uri.parse('$apiUrl/auth/profile'); | 
					
						
							|  |  |  |     final response = await _client.delete(uri); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (response.statusCode != 200) { | 
					
						
							|  |  |  |       throw Exception('Failed to delete account: ${response.body}'); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // ============================================
 | 
					
						
							|  |  |  |   // Movies Endpoints
 | 
					
						
							|  |  |  |   // ============================================
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /// Get popular movies
 | 
					
						
							|  |  |  |   Future<List<Movie>> getPopularMovies({int page = 1}) async { | 
					
						
							|  |  |  |     return _fetchMovies('/movies/popular', page: page); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /// Get top rated movies
 | 
					
						
							|  |  |  |   Future<List<Movie>> getTopRatedMovies({int page = 1}) async { | 
					
						
							|  |  |  |     return _fetchMovies('/movies/top-rated', page: page); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /// Get upcoming movies
 | 
					
						
							|  |  |  |   Future<List<Movie>> getUpcomingMovies({int page = 1}) async { | 
					
						
							|  |  |  |     return _fetchMovies('/movies/upcoming', page: page); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /// Get now playing movies
 | 
					
						
							|  |  |  |   Future<List<Movie>> getNowPlayingMovies({int page = 1}) async { | 
					
						
							|  |  |  |     return _fetchMovies('/movies/now-playing', page: page); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /// Get movie by ID
 | 
					
						
							|  |  |  |   Future<Movie> getMovieById(String id) async { | 
					
						
							|  |  |  |     final uri = Uri.parse('$apiUrl/movies/$id'); | 
					
						
							|  |  |  |     final response = await _client.get(uri); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (response.statusCode == 200) { | 
					
						
							| 
									
										
										
										
											2025-10-02 19:54:32 +00:00
										 |  |  |       final apiResponse = json.decode(response.body); | 
					
						
							|  |  |  |       // API returns: {"success": true, "data": {...}}
 | 
					
						
							|  |  |  |       final movieData = (apiResponse is Map && apiResponse['data'] != null)  | 
					
						
							|  |  |  |           ? apiResponse['data']  | 
					
						
							|  |  |  |           : apiResponse; | 
					
						
							|  |  |  |       return Movie.fromJson(movieData); | 
					
						
							| 
									
										
											![factory-droid[bot]](/assets/img/avatar_default.png)  
											
												feat: Add TorrentEngine library and new API client
- Created complete TorrentEngine library module with LibTorrent4j
  - Full torrent management (add, pause, resume, remove)
  - Magnet link metadata extraction
  - File priority management (even during download)
  - Foreground service with persistent notification
  - Room database for state persistence
  - Reactive Flow API for UI updates
- Integrated TorrentEngine with MainActivity via MethodChannel
  - addTorrent, getTorrents, pauseTorrent, resumeTorrent, removeTorrent
  - setFilePriority for dynamic file selection
  - Full JSON serialization for Flutter communication
- Created new NeoMoviesApiClient for Go-based backend
  - Email verification flow (register, verify, resendCode)
  - Google OAuth support
  - Torrent search via RedAPI
  - Multiple player support (Alloha, Lumex, Vibix)
  - Enhanced reactions system (likes/dislikes)
  - All movies/TV shows endpoints
- Updated dependencies and build configuration
  - Java 17 compatibility
  - Updated Kotlin coroutines to 1.9.0
  - Fixed build_runner version conflict
  - Added torrentengine module to settings.gradle.kts
- Added comprehensive documentation
  - TorrentEngine README with usage examples
  - DEVELOPMENT_SUMMARY with full implementation details
  - ProGuard rules for library
This is a complete rewrite of torrent functionality as a reusable library.
											
										 
											2025-10-02 10:56:22 +00:00
										 |  |  |     } else { | 
					
						
							|  |  |  |       throw Exception('Failed to load movie: ${response.statusCode}'); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /// Get movie recommendations
 | 
					
						
							|  |  |  |   Future<List<Movie>> getMovieRecommendations(String movieId, {int page = 1}) async { | 
					
						
							|  |  |  |     return _fetchMovies('/movies/$movieId/recommendations', page: page); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /// Search movies
 | 
					
						
							|  |  |  |   Future<List<Movie>> searchMovies(String query, {int page = 1}) async { | 
					
						
							|  |  |  |     return _fetchMovies('/movies/search', page: page, query: query); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // ============================================
 | 
					
						
							|  |  |  |   // TV Shows Endpoints
 | 
					
						
							|  |  |  |   // ============================================
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /// Get popular TV shows
 | 
					
						
							|  |  |  |   Future<List<Movie>> getPopularTvShows({int page = 1}) async { | 
					
						
							|  |  |  |     return _fetchMovies('/tv/popular', page: page); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /// Get top rated TV shows
 | 
					
						
							|  |  |  |   Future<List<Movie>> getTopRatedTvShows({int page = 1}) async { | 
					
						
							|  |  |  |     return _fetchMovies('/tv/top-rated', page: page); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /// Get TV show by ID
 | 
					
						
							|  |  |  |   Future<Movie> getTvShowById(String id) async { | 
					
						
							|  |  |  |     final uri = Uri.parse('$apiUrl/tv/$id'); | 
					
						
							|  |  |  |     final response = await _client.get(uri); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (response.statusCode == 200) { | 
					
						
							| 
									
										
										
										
											2025-10-02 19:54:32 +00:00
										 |  |  |       final apiResponse = json.decode(response.body); | 
					
						
							|  |  |  |       // API returns: {"success": true, "data": {...}}
 | 
					
						
							|  |  |  |       final tvData = (apiResponse is Map && apiResponse['data'] != null)  | 
					
						
							|  |  |  |           ? apiResponse['data']  | 
					
						
							|  |  |  |           : apiResponse; | 
					
						
							|  |  |  |       return Movie.fromJson(tvData); | 
					
						
							| 
									
										
											![factory-droid[bot]](/assets/img/avatar_default.png)  
											
												feat: Add TorrentEngine library and new API client
- Created complete TorrentEngine library module with LibTorrent4j
  - Full torrent management (add, pause, resume, remove)
  - Magnet link metadata extraction
  - File priority management (even during download)
  - Foreground service with persistent notification
  - Room database for state persistence
  - Reactive Flow API for UI updates
- Integrated TorrentEngine with MainActivity via MethodChannel
  - addTorrent, getTorrents, pauseTorrent, resumeTorrent, removeTorrent
  - setFilePriority for dynamic file selection
  - Full JSON serialization for Flutter communication
- Created new NeoMoviesApiClient for Go-based backend
  - Email verification flow (register, verify, resendCode)
  - Google OAuth support
  - Torrent search via RedAPI
  - Multiple player support (Alloha, Lumex, Vibix)
  - Enhanced reactions system (likes/dislikes)
  - All movies/TV shows endpoints
- Updated dependencies and build configuration
  - Java 17 compatibility
  - Updated Kotlin coroutines to 1.9.0
  - Fixed build_runner version conflict
  - Added torrentengine module to settings.gradle.kts
- Added comprehensive documentation
  - TorrentEngine README with usage examples
  - DEVELOPMENT_SUMMARY with full implementation details
  - ProGuard rules for library
This is a complete rewrite of torrent functionality as a reusable library.
											
										 
											2025-10-02 10:56:22 +00:00
										 |  |  |     } else { | 
					
						
							|  |  |  |       throw Exception('Failed to load TV show: ${response.statusCode}'); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /// Get TV show recommendations
 | 
					
						
							|  |  |  |   Future<List<Movie>> getTvShowRecommendations(String tvId, {int page = 1}) async { | 
					
						
							|  |  |  |     return _fetchMovies('/tv/$tvId/recommendations', page: page); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /// Search TV shows
 | 
					
						
							|  |  |  |   Future<List<Movie>> searchTvShows(String query, {int page = 1}) async { | 
					
						
							|  |  |  |     return _fetchMovies('/tv/search', page: page, query: query); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // ============================================
 | 
					
						
							|  |  |  |   // Unified Search
 | 
					
						
							|  |  |  |   // ============================================
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /// Search both movies and TV shows
 | 
					
						
							|  |  |  |   Future<List<Movie>> search(String query, {int page = 1}) async { | 
					
						
							|  |  |  |     final results = await Future.wait([ | 
					
						
							|  |  |  |       searchMovies(query, page: page), | 
					
						
							|  |  |  |       searchTvShows(query, page: page), | 
					
						
							|  |  |  |     ]); | 
					
						
							|  |  |  |      | 
					
						
							|  |  |  |     // Combine and return
 | 
					
						
							|  |  |  |     return [...results[0], ...results[1]]; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // ============================================
 | 
					
						
							|  |  |  |   // Favorites Endpoints
 | 
					
						
							|  |  |  |   // ============================================
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /// Get user's favorite movies/shows
 | 
					
						
							|  |  |  |   Future<List<Favorite>> getFavorites() async { | 
					
						
							|  |  |  |     final uri = Uri.parse('$apiUrl/favorites'); | 
					
						
							|  |  |  |     final response = await _client.get(uri); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (response.statusCode == 200) { | 
					
						
							| 
									
										
										
										
											2025-10-02 19:54:32 +00:00
										 |  |  |       final apiResponse = json.decode(response.body); | 
					
						
							|  |  |  |       // API returns: {"success": true, "data": [...]}
 | 
					
						
							|  |  |  |       final List<dynamic> data = (apiResponse is Map && apiResponse['data'] != null) | 
					
						
							|  |  |  |           ? (apiResponse['data'] is List ? apiResponse['data'] : []) | 
					
						
							|  |  |  |           : (apiResponse is List ? apiResponse : []); | 
					
						
							| 
									
										
											![factory-droid[bot]](/assets/img/avatar_default.png)  
											
												feat: Add TorrentEngine library and new API client
- Created complete TorrentEngine library module with LibTorrent4j
  - Full torrent management (add, pause, resume, remove)
  - Magnet link metadata extraction
  - File priority management (even during download)
  - Foreground service with persistent notification
  - Room database for state persistence
  - Reactive Flow API for UI updates
- Integrated TorrentEngine with MainActivity via MethodChannel
  - addTorrent, getTorrents, pauseTorrent, resumeTorrent, removeTorrent
  - setFilePriority for dynamic file selection
  - Full JSON serialization for Flutter communication
- Created new NeoMoviesApiClient for Go-based backend
  - Email verification flow (register, verify, resendCode)
  - Google OAuth support
  - Torrent search via RedAPI
  - Multiple player support (Alloha, Lumex, Vibix)
  - Enhanced reactions system (likes/dislikes)
  - All movies/TV shows endpoints
- Updated dependencies and build configuration
  - Java 17 compatibility
  - Updated Kotlin coroutines to 1.9.0
  - Fixed build_runner version conflict
  - Added torrentengine module to settings.gradle.kts
- Added comprehensive documentation
  - TorrentEngine README with usage examples
  - DEVELOPMENT_SUMMARY with full implementation details
  - ProGuard rules for library
This is a complete rewrite of torrent functionality as a reusable library.
											
										 
											2025-10-02 10:56:22 +00:00
										 |  |  |       return data.map((json) => Favorite.fromJson(json)).toList(); | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |       throw Exception('Failed to fetch favorites: ${response.body}'); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /// Add movie/show to favorites
 | 
					
						
							| 
									
										
										
										
											2025-10-02 19:54:32 +00:00
										 |  |  |   /// Backend automatically fetches title and poster_path from TMDB
 | 
					
						
							| 
									
										
											![factory-droid[bot]](/assets/img/avatar_default.png)  
											
												feat: Add TorrentEngine library and new API client
- Created complete TorrentEngine library module with LibTorrent4j
  - Full torrent management (add, pause, resume, remove)
  - Magnet link metadata extraction
  - File priority management (even during download)
  - Foreground service with persistent notification
  - Room database for state persistence
  - Reactive Flow API for UI updates
- Integrated TorrentEngine with MainActivity via MethodChannel
  - addTorrent, getTorrents, pauseTorrent, resumeTorrent, removeTorrent
  - setFilePriority for dynamic file selection
  - Full JSON serialization for Flutter communication
- Created new NeoMoviesApiClient for Go-based backend
  - Email verification flow (register, verify, resendCode)
  - Google OAuth support
  - Torrent search via RedAPI
  - Multiple player support (Alloha, Lumex, Vibix)
  - Enhanced reactions system (likes/dislikes)
  - All movies/TV shows endpoints
- Updated dependencies and build configuration
  - Java 17 compatibility
  - Updated Kotlin coroutines to 1.9.0
  - Fixed build_runner version conflict
  - Added torrentengine module to settings.gradle.kts
- Added comprehensive documentation
  - TorrentEngine README with usage examples
  - DEVELOPMENT_SUMMARY with full implementation details
  - ProGuard rules for library
This is a complete rewrite of torrent functionality as a reusable library.
											
										 
											2025-10-02 10:56:22 +00:00
										 |  |  |   Future<void> addFavorite({ | 
					
						
							|  |  |  |     required String mediaId, | 
					
						
							|  |  |  |     required String mediaType, | 
					
						
							|  |  |  |     required String title, | 
					
						
							|  |  |  |     required String posterPath, | 
					
						
							|  |  |  |   }) async { | 
					
						
							| 
									
										
										
										
											2025-10-02 19:54:32 +00:00
										 |  |  |     // Backend route: POST /favorites/{id}?type={mediaType}
 | 
					
						
							|  |  |  |     final uri = Uri.parse('$apiUrl/favorites/$mediaId') | 
					
						
							|  |  |  |         .replace(queryParameters: {'type': mediaType}); | 
					
						
							|  |  |  |     final response = await _client.post(uri); | 
					
						
							| 
									
										
											![factory-droid[bot]](/assets/img/avatar_default.png)  
											
												feat: Add TorrentEngine library and new API client
- Created complete TorrentEngine library module with LibTorrent4j
  - Full torrent management (add, pause, resume, remove)
  - Magnet link metadata extraction
  - File priority management (even during download)
  - Foreground service with persistent notification
  - Room database for state persistence
  - Reactive Flow API for UI updates
- Integrated TorrentEngine with MainActivity via MethodChannel
  - addTorrent, getTorrents, pauseTorrent, resumeTorrent, removeTorrent
  - setFilePriority for dynamic file selection
  - Full JSON serialization for Flutter communication
- Created new NeoMoviesApiClient for Go-based backend
  - Email verification flow (register, verify, resendCode)
  - Google OAuth support
  - Torrent search via RedAPI
  - Multiple player support (Alloha, Lumex, Vibix)
  - Enhanced reactions system (likes/dislikes)
  - All movies/TV shows endpoints
- Updated dependencies and build configuration
  - Java 17 compatibility
  - Updated Kotlin coroutines to 1.9.0
  - Fixed build_runner version conflict
  - Added torrentengine module to settings.gradle.kts
- Added comprehensive documentation
  - TorrentEngine README with usage examples
  - DEVELOPMENT_SUMMARY with full implementation details
  - ProGuard rules for library
This is a complete rewrite of torrent functionality as a reusable library.
											
										 
											2025-10-02 10:56:22 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if (response.statusCode != 200 && response.statusCode != 201) { | 
					
						
							|  |  |  |       throw Exception('Failed to add favorite: ${response.body}'); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /// Remove movie/show from favorites
 | 
					
						
							| 
									
										
										
										
											2025-10-02 19:54:32 +00:00
										 |  |  |   Future<void> removeFavorite(String mediaId, {String mediaType = 'movie'}) async { | 
					
						
							|  |  |  |     // Backend route: DELETE /favorites/{id}?type={mediaType}
 | 
					
						
							|  |  |  |     final uri = Uri.parse('$apiUrl/favorites/$mediaId') | 
					
						
							|  |  |  |         .replace(queryParameters: {'type': mediaType}); | 
					
						
							| 
									
										
											![factory-droid[bot]](/assets/img/avatar_default.png)  
											
												feat: Add TorrentEngine library and new API client
- Created complete TorrentEngine library module with LibTorrent4j
  - Full torrent management (add, pause, resume, remove)
  - Magnet link metadata extraction
  - File priority management (even during download)
  - Foreground service with persistent notification
  - Room database for state persistence
  - Reactive Flow API for UI updates
- Integrated TorrentEngine with MainActivity via MethodChannel
  - addTorrent, getTorrents, pauseTorrent, resumeTorrent, removeTorrent
  - setFilePriority for dynamic file selection
  - Full JSON serialization for Flutter communication
- Created new NeoMoviesApiClient for Go-based backend
  - Email verification flow (register, verify, resendCode)
  - Google OAuth support
  - Torrent search via RedAPI
  - Multiple player support (Alloha, Lumex, Vibix)
  - Enhanced reactions system (likes/dislikes)
  - All movies/TV shows endpoints
- Updated dependencies and build configuration
  - Java 17 compatibility
  - Updated Kotlin coroutines to 1.9.0
  - Fixed build_runner version conflict
  - Added torrentengine module to settings.gradle.kts
- Added comprehensive documentation
  - TorrentEngine README with usage examples
  - DEVELOPMENT_SUMMARY with full implementation details
  - ProGuard rules for library
This is a complete rewrite of torrent functionality as a reusable library.
											
										 
											2025-10-02 10:56:22 +00:00
										 |  |  |     final response = await _client.delete(uri); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (response.statusCode != 200 && response.statusCode != 204) { | 
					
						
							|  |  |  |       throw Exception('Failed to remove favorite: ${response.body}'); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-10-02 19:54:32 +00:00
										 |  |  |   /// Check if media is in favorites
 | 
					
						
							|  |  |  |   Future<bool> checkIsFavorite(String mediaId, {String mediaType = 'movie'}) async { | 
					
						
							|  |  |  |     // Backend route: GET /favorites/{id}/check?type={mediaType}
 | 
					
						
							|  |  |  |     final uri = Uri.parse('$apiUrl/favorites/$mediaId/check') | 
					
						
							|  |  |  |         .replace(queryParameters: {'type': mediaType}); | 
					
						
							|  |  |  |     final response = await _client.get(uri); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (response.statusCode == 200) { | 
					
						
							|  |  |  |       final apiResponse = json.decode(response.body); | 
					
						
							|  |  |  |       // API returns: {"success": true, "data": {"isFavorite": true}}
 | 
					
						
							|  |  |  |       if (apiResponse is Map && apiResponse['data'] != null) { | 
					
						
							|  |  |  |         final data = apiResponse['data']; | 
					
						
							|  |  |  |         return data['isFavorite'] ?? false; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       return false; | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |       throw Exception('Failed to check favorite status: ${response.body}'); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											![factory-droid[bot]](/assets/img/avatar_default.png)  
											
												feat: Add TorrentEngine library and new API client
- Created complete TorrentEngine library module with LibTorrent4j
  - Full torrent management (add, pause, resume, remove)
  - Magnet link metadata extraction
  - File priority management (even during download)
  - Foreground service with persistent notification
  - Room database for state persistence
  - Reactive Flow API for UI updates
- Integrated TorrentEngine with MainActivity via MethodChannel
  - addTorrent, getTorrents, pauseTorrent, resumeTorrent, removeTorrent
  - setFilePriority for dynamic file selection
  - Full JSON serialization for Flutter communication
- Created new NeoMoviesApiClient for Go-based backend
  - Email verification flow (register, verify, resendCode)
  - Google OAuth support
  - Torrent search via RedAPI
  - Multiple player support (Alloha, Lumex, Vibix)
  - Enhanced reactions system (likes/dislikes)
  - All movies/TV shows endpoints
- Updated dependencies and build configuration
  - Java 17 compatibility
  - Updated Kotlin coroutines to 1.9.0
  - Fixed build_runner version conflict
  - Added torrentengine module to settings.gradle.kts
- Added comprehensive documentation
  - TorrentEngine README with usage examples
  - DEVELOPMENT_SUMMARY with full implementation details
  - ProGuard rules for library
This is a complete rewrite of torrent functionality as a reusable library.
											
										 
											2025-10-02 10:56:22 +00:00
										 |  |  |   // ============================================
 | 
					
						
							|  |  |  |   // Reactions Endpoints (NEW!)
 | 
					
						
							|  |  |  |   // ============================================
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /// Get reaction counts for a movie/show
 | 
					
						
							|  |  |  |   Future<Map<String, int>> getReactionCounts({ | 
					
						
							|  |  |  |     required String mediaType, | 
					
						
							|  |  |  |     required String mediaId, | 
					
						
							|  |  |  |   }) async { | 
					
						
							|  |  |  |     final uri = Uri.parse('$apiUrl/reactions/$mediaType/$mediaId/counts'); | 
					
						
							|  |  |  |     final response = await _client.get(uri); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (response.statusCode == 200) { | 
					
						
							|  |  |  |       final data = json.decode(response.body); | 
					
						
							|  |  |  |       return Map<String, int>.from(data); | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |       throw Exception('Failed to get reactions: ${response.body}'); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /// Add or update user's reaction
 | 
					
						
							|  |  |  |   Future<void> setReaction({ | 
					
						
							|  |  |  |     required String mediaType, | 
					
						
							|  |  |  |     required String mediaId, | 
					
						
							|  |  |  |     required String reactionType, // 'like' or 'dislike'
 | 
					
						
							|  |  |  |   }) async { | 
					
						
							|  |  |  |     final uri = Uri.parse('$apiUrl/reactions/$mediaType/$mediaId'); | 
					
						
							|  |  |  |     final response = await _client.post( | 
					
						
							|  |  |  |       uri, | 
					
						
							|  |  |  |       headers: {'Content-Type': 'application/json'}, | 
					
						
							|  |  |  |       body: json.encode({'type': reactionType}), | 
					
						
							|  |  |  |     ); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (response.statusCode != 200 && response.statusCode != 201) { | 
					
						
							|  |  |  |       throw Exception('Failed to set reaction: ${response.body}'); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /// Get user's own reactions
 | 
					
						
							|  |  |  |   Future<List<UserReaction>> getMyReactions() async { | 
					
						
							|  |  |  |     final uri = Uri.parse('$apiUrl/reactions/my'); | 
					
						
							|  |  |  |     final response = await _client.get(uri); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (response.statusCode == 200) { | 
					
						
							| 
									
										
										
										
											2025-10-02 19:54:32 +00:00
										 |  |  |       final apiResponse = json.decode(response.body); | 
					
						
							|  |  |  |       // API returns: {"success": true, "data": [...]}
 | 
					
						
							|  |  |  |       final List<dynamic> data = (apiResponse is Map && apiResponse['data'] != null) | 
					
						
							|  |  |  |           ? (apiResponse['data'] is List ? apiResponse['data'] : []) | 
					
						
							|  |  |  |           : (apiResponse is List ? apiResponse : []); | 
					
						
							| 
									
										
											![factory-droid[bot]](/assets/img/avatar_default.png)  
											
												feat: Add TorrentEngine library and new API client
- Created complete TorrentEngine library module with LibTorrent4j
  - Full torrent management (add, pause, resume, remove)
  - Magnet link metadata extraction
  - File priority management (even during download)
  - Foreground service with persistent notification
  - Room database for state persistence
  - Reactive Flow API for UI updates
- Integrated TorrentEngine with MainActivity via MethodChannel
  - addTorrent, getTorrents, pauseTorrent, resumeTorrent, removeTorrent
  - setFilePriority for dynamic file selection
  - Full JSON serialization for Flutter communication
- Created new NeoMoviesApiClient for Go-based backend
  - Email verification flow (register, verify, resendCode)
  - Google OAuth support
  - Torrent search via RedAPI
  - Multiple player support (Alloha, Lumex, Vibix)
  - Enhanced reactions system (likes/dislikes)
  - All movies/TV shows endpoints
- Updated dependencies and build configuration
  - Java 17 compatibility
  - Updated Kotlin coroutines to 1.9.0
  - Fixed build_runner version conflict
  - Added torrentengine module to settings.gradle.kts
- Added comprehensive documentation
  - TorrentEngine README with usage examples
  - DEVELOPMENT_SUMMARY with full implementation details
  - ProGuard rules for library
This is a complete rewrite of torrent functionality as a reusable library.
											
										 
											2025-10-02 10:56:22 +00:00
										 |  |  |       return data.map((json) => UserReaction.fromJson(json)).toList(); | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |       throw Exception('Failed to get my reactions: ${response.body}'); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // ============================================
 | 
					
						
							|  |  |  |   // Torrent Search Endpoints (NEW!)
 | 
					
						
							|  |  |  |   // ============================================
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /// Search torrents for a movie/show via RedAPI
 | 
					
						
							|  |  |  |   /// @param imdbId - IMDb ID (e.g., "tt1234567")
 | 
					
						
							|  |  |  |   /// @param type - "movie" or "series"
 | 
					
						
							|  |  |  |   /// @param quality - "1080p", "720p", "480p", etc.
 | 
					
						
							|  |  |  |   Future<List<TorrentItem>> searchTorrents({ | 
					
						
							|  |  |  |     required String imdbId, | 
					
						
							|  |  |  |     required String type, | 
					
						
							|  |  |  |     String? quality, | 
					
						
							|  |  |  |     String? season, | 
					
						
							|  |  |  |     String? episode, | 
					
						
							|  |  |  |   }) async { | 
					
						
							|  |  |  |     final queryParams = { | 
					
						
							|  |  |  |       'type': type, | 
					
						
							|  |  |  |       if (quality != null) 'quality': quality, | 
					
						
							|  |  |  |       if (season != null) 'season': season, | 
					
						
							|  |  |  |       if (episode != null) 'episode': episode, | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     final uri = Uri.parse('$apiUrl/torrents/search/$imdbId') | 
					
						
							|  |  |  |         .replace(queryParameters: queryParams); | 
					
						
							|  |  |  |      | 
					
						
							|  |  |  |     final response = await _client.get(uri); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (response.statusCode == 200) { | 
					
						
							|  |  |  |       final List<dynamic> data = json.decode(response.body); | 
					
						
							|  |  |  |       return data.map((json) => TorrentItem.fromJson(json)).toList(); | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |       throw Exception('Failed to search torrents: ${response.body}'); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // ============================================
 | 
					
						
							|  |  |  |   // Players Endpoints (NEW!)
 | 
					
						
							|  |  |  |   // ============================================
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /// Get Alloha player embed URL
 | 
					
						
							|  |  |  |   Future<PlayerResponse> getAllohaPlayer(String imdbId) async { | 
					
						
							|  |  |  |     return _getPlayer('/players/alloha/$imdbId'); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /// Get Lumex player embed URL
 | 
					
						
							|  |  |  |   Future<PlayerResponse> getLumexPlayer(String imdbId) async { | 
					
						
							|  |  |  |     return _getPlayer('/players/lumex/$imdbId'); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /// Get Vibix player embed URL
 | 
					
						
							|  |  |  |   Future<PlayerResponse> getVibixPlayer(String imdbId) async { | 
					
						
							|  |  |  |     return _getPlayer('/players/vibix/$imdbId'); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // ============================================
 | 
					
						
							|  |  |  |   // Private Helper Methods
 | 
					
						
							|  |  |  |   // ============================================
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /// Generic method to fetch movies/TV shows
 | 
					
						
							|  |  |  |   Future<List<Movie>> _fetchMovies( | 
					
						
							|  |  |  |     String endpoint, { | 
					
						
							|  |  |  |     int page = 1, | 
					
						
							|  |  |  |     String? query, | 
					
						
							|  |  |  |   }) async { | 
					
						
							|  |  |  |     final queryParams = { | 
					
						
							|  |  |  |       'page': page.toString(), | 
					
						
							|  |  |  |       if (query != null && query.isNotEmpty) 'query': query, | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     final uri = Uri.parse('$apiUrl$endpoint').replace(queryParameters: queryParams); | 
					
						
							|  |  |  |     final response = await _client.get(uri); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (response.statusCode == 200) { | 
					
						
							|  |  |  |       final decoded = json.decode(response.body); | 
					
						
							|  |  |  |        | 
					
						
							| 
									
										
										
										
											2025-10-02 19:54:32 +00:00
										 |  |  |       // API returns: {"success": true, "data": {"page": 1, "results": [...], ...}}
 | 
					
						
							| 
									
										
											![factory-droid[bot]](/assets/img/avatar_default.png)  
											
												feat: Add TorrentEngine library and new API client
- Created complete TorrentEngine library module with LibTorrent4j
  - Full torrent management (add, pause, resume, remove)
  - Magnet link metadata extraction
  - File priority management (even during download)
  - Foreground service with persistent notification
  - Room database for state persistence
  - Reactive Flow API for UI updates
- Integrated TorrentEngine with MainActivity via MethodChannel
  - addTorrent, getTorrents, pauseTorrent, resumeTorrent, removeTorrent
  - setFilePriority for dynamic file selection
  - Full JSON serialization for Flutter communication
- Created new NeoMoviesApiClient for Go-based backend
  - Email verification flow (register, verify, resendCode)
  - Google OAuth support
  - Torrent search via RedAPI
  - Multiple player support (Alloha, Lumex, Vibix)
  - Enhanced reactions system (likes/dislikes)
  - All movies/TV shows endpoints
- Updated dependencies and build configuration
  - Java 17 compatibility
  - Updated Kotlin coroutines to 1.9.0
  - Fixed build_runner version conflict
  - Added torrentengine module to settings.gradle.kts
- Added comprehensive documentation
  - TorrentEngine README with usage examples
  - DEVELOPMENT_SUMMARY with full implementation details
  - ProGuard rules for library
This is a complete rewrite of torrent functionality as a reusable library.
											
										 
											2025-10-02 10:56:22 +00:00
										 |  |  |       List<dynamic> results; | 
					
						
							| 
									
										
										
										
											2025-10-02 19:54:32 +00:00
										 |  |  |       if (decoded is Map && decoded['success'] == true && decoded['data'] != null) { | 
					
						
							|  |  |  |         final data = decoded['data']; | 
					
						
							|  |  |  |         if (data is Map && data['results'] != null) { | 
					
						
							|  |  |  |           results = data['results']; | 
					
						
							|  |  |  |         } else if (data is List) { | 
					
						
							|  |  |  |           results = data; | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |           throw Exception('Unexpected data format in API response'); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } else if (decoded is List) { | 
					
						
							| 
									
										
											![factory-droid[bot]](/assets/img/avatar_default.png)  
											
												feat: Add TorrentEngine library and new API client
- Created complete TorrentEngine library module with LibTorrent4j
  - Full torrent management (add, pause, resume, remove)
  - Magnet link metadata extraction
  - File priority management (even during download)
  - Foreground service with persistent notification
  - Room database for state persistence
  - Reactive Flow API for UI updates
- Integrated TorrentEngine with MainActivity via MethodChannel
  - addTorrent, getTorrents, pauseTorrent, resumeTorrent, removeTorrent
  - setFilePriority for dynamic file selection
  - Full JSON serialization for Flutter communication
- Created new NeoMoviesApiClient for Go-based backend
  - Email verification flow (register, verify, resendCode)
  - Google OAuth support
  - Torrent search via RedAPI
  - Multiple player support (Alloha, Lumex, Vibix)
  - Enhanced reactions system (likes/dislikes)
  - All movies/TV shows endpoints
- Updated dependencies and build configuration
  - Java 17 compatibility
  - Updated Kotlin coroutines to 1.9.0
  - Fixed build_runner version conflict
  - Added torrentengine module to settings.gradle.kts
- Added comprehensive documentation
  - TorrentEngine README with usage examples
  - DEVELOPMENT_SUMMARY with full implementation details
  - ProGuard rules for library
This is a complete rewrite of torrent functionality as a reusable library.
											
										 
											2025-10-02 10:56:22 +00:00
										 |  |  |         results = decoded; | 
					
						
							|  |  |  |       } else if (decoded is Map && decoded['results'] != null) { | 
					
						
							|  |  |  |         results = decoded['results']; | 
					
						
							|  |  |  |       } else { | 
					
						
							|  |  |  |         throw Exception('Unexpected response format'); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       return results.map((json) => Movie.fromJson(json)).toList(); | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |       throw Exception('Failed to load from $endpoint: ${response.statusCode}'); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /// Generic method to fetch player info
 | 
					
						
							|  |  |  |   Future<PlayerResponse> _getPlayer(String endpoint) async { | 
					
						
							|  |  |  |     final uri = Uri.parse('$apiUrl$endpoint'); | 
					
						
							|  |  |  |     final response = await _client.get(uri); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (response.statusCode == 200) { | 
					
						
							|  |  |  |       return PlayerResponse.fromJson(json.decode(response.body)); | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |       throw Exception('Failed to get player: ${response.body}'); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } |