mirror of
https://gitlab.com/foxixus/neomovies_mobile.git
synced 2025-10-28 01:18:50 +05:00
Added extensive logging throughout DownloadsProvider and DownloadsScreen to diagnose why downloads screen appears empty. DownloadsProvider.refreshDownloads(): - 📥 Log function call - 📥 Log state changes (loading, error) - 📥 Log TorrentPlatformService.getAllDownloads() call - 📥 Log number of torrents received - 📥 Log each torrent processing with index - 📥 Log success/failure for each torrent info fetch - 📥 Log final torrents count - 📥 Log completion or error state DownloadsScreen.initState() and Consumer: - 📥 Log initState call - 📥 Log postFrameCallback execution - 📥 Log Consumer builder invocations - 📥 Log provider state (isLoading, error, torrents.length) - 📥 Log which UI is displayed: * CircularProgressIndicator * ErrorDisplay * Empty state message * Torrent list with count All logs prefixed with 📥 for easy filtering in logcat. Example output: --- 📥 DownloadsScreen: initState() called 📥 DownloadsScreen: postFrameCallback, calling refreshDownloads() 📥 DownloadsProvider: refreshDownloads() called 📥 Setting loading=true, error=null 📥 Calling TorrentPlatformService.getAllDownloads()... 📥 Got 0 torrents from platform service 📥 Cleared _torrents list 📥 Final torrents count: 0 📥 Setting loading=false 📥 ✅ refreshDownloads() completed successfully 📥 DownloadsScreen: Consumer builder called 📥 isLoading: false 📥 error: null 📥 torrents.length: 0 📥 → Showing empty state This will help identify: - Is refreshDownloads being called? - Does TorrentPlatformService return any data? - Are torrents parsed correctly? - Is the correct UI state shown? - Where does the process fail? Usage: Run app → Open Downloads screen → Check logcat for 📥 logs
190 lines
6.2 KiB
Dart
190 lines
6.2 KiB
Dart
import 'dart:async';
|
||
import 'package:flutter/foundation.dart';
|
||
import '../../data/services/torrent_platform_service.dart';
|
||
import '../../data/models/torrent_info.dart';
|
||
|
||
/// Provider для управления загрузками торрентов
|
||
class DownloadsProvider with ChangeNotifier {
|
||
final List<TorrentInfo> _torrents = [];
|
||
Timer? _progressTimer;
|
||
bool _isLoading = false;
|
||
String? _error;
|
||
String? _stackTrace;
|
||
|
||
List<TorrentInfo> get torrents => List.unmodifiable(_torrents);
|
||
bool get isLoading => _isLoading;
|
||
String? get error => _error;
|
||
String? get stackTrace => _stackTrace;
|
||
|
||
DownloadsProvider() {
|
||
_startProgressUpdates();
|
||
}
|
||
|
||
@override
|
||
void dispose() {
|
||
_progressTimer?.cancel();
|
||
super.dispose();
|
||
}
|
||
|
||
void _startProgressUpdates() {
|
||
_progressTimer = Timer.periodic(const Duration(seconds: 3), (timer) {
|
||
if (_torrents.isNotEmpty && !_isLoading) {
|
||
refreshDownloads();
|
||
}
|
||
});
|
||
}
|
||
|
||
/// Загрузить список активных загрузок
|
||
Future<void> refreshDownloads() async {
|
||
print('📥 DownloadsProvider: refreshDownloads() called');
|
||
try {
|
||
print('📥 Setting loading=true, error=null');
|
||
_setLoading(true);
|
||
_setError(null);
|
||
|
||
print('📥 Calling TorrentPlatformService.getAllDownloads()...');
|
||
final progress = await TorrentPlatformService.getAllDownloads();
|
||
print('📥 Got ${progress.length} torrents from platform service');
|
||
|
||
// Получаем полную информацию о каждом торренте
|
||
_torrents.clear();
|
||
print('📥 Cleared _torrents list');
|
||
|
||
for (int i = 0; i < progress.length; i++) {
|
||
final progressItem = progress[i];
|
||
print('📥 Processing torrent $i: ${progressItem.infoHash.substring(0, 8)}...');
|
||
try {
|
||
final torrentInfo = await TorrentPlatformService.getTorrent(progressItem.infoHash);
|
||
if (torrentInfo != null) {
|
||
_torrents.add(torrentInfo);
|
||
}
|
||
} catch (e) {
|
||
// Если не удалось получить полную информацию, создаем базовую
|
||
_torrents.add(TorrentInfo(
|
||
infoHash: progressItem.infoHash,
|
||
name: 'Торрент ${progressItem.infoHash.substring(0, 8)}',
|
||
totalSize: 0,
|
||
progress: progressItem.progress,
|
||
downloadSpeed: progressItem.downloadRate,
|
||
uploadSpeed: progressItem.uploadRate,
|
||
numSeeds: progressItem.numSeeds,
|
||
numPeers: progressItem.numPeers,
|
||
state: progressItem.state,
|
||
savePath: '/storage/emulated/0/Download/NeoMovies',
|
||
files: [],
|
||
);
|
||
print('📥 ✅ Created basic info: ${basicInfo.name}');
|
||
_torrents.add(basicInfo);
|
||
}
|
||
}
|
||
|
||
print('📥 Final torrents count: ${_torrents.length}');
|
||
print('📥 Setting loading=false');
|
||
_setLoading(false);
|
||
print('📥 ✅ refreshDownloads() completed successfully');
|
||
} catch (e, stackTrace) {
|
||
print('📥 ❌ Error refreshing downloads: $e');
|
||
print('📥 Stack trace: $stackTrace');
|
||
_setError(e.toString(), stackTrace.toString());
|
||
_setLoading(false);
|
||
print('📥 Error state set, loading=false');
|
||
}
|
||
}
|
||
|
||
/// Получить информацию о конкретном торренте
|
||
Future<TorrentInfo?> getTorrentInfo(String infoHash) async {
|
||
try {
|
||
return await TorrentPlatformService.getTorrent(infoHash);
|
||
} catch (e) {
|
||
debugPrint('Ошибка получения информации о торренте: $e');
|
||
return null;
|
||
}
|
||
}
|
||
|
||
/// Приостановить торрент
|
||
Future<void> pauseTorrent(String infoHash) async {
|
||
try {
|
||
await TorrentPlatformService.pauseDownload(infoHash);
|
||
await refreshDownloads(); // Обновляем список
|
||
} catch (e) {
|
||
_setError(e.toString());
|
||
}
|
||
}
|
||
|
||
/// Возобновить торрент
|
||
Future<void> resumeTorrent(String infoHash) async {
|
||
try {
|
||
await TorrentPlatformService.resumeDownload(infoHash);
|
||
await refreshDownloads(); // Обновляем список
|
||
} catch (e) {
|
||
_setError(e.toString());
|
||
}
|
||
}
|
||
|
||
/// Удалить торрент
|
||
Future<void> removeTorrent(String infoHash) async {
|
||
try {
|
||
await TorrentPlatformService.cancelDownload(infoHash);
|
||
await refreshDownloads(); // Обновляем список
|
||
} catch (e) {
|
||
_setError(e.toString());
|
||
}
|
||
}
|
||
|
||
/// Установить приоритет файла
|
||
Future<void> setFilePriority(String infoHash, int fileIndex, FilePriority priority) async {
|
||
try {
|
||
await TorrentPlatformService.setFilePriority(infoHash, fileIndex, priority);
|
||
} catch (e) {
|
||
_setError(e.toString());
|
||
}
|
||
}
|
||
|
||
/// Добавить новый торрент
|
||
Future<String?> addTorrent(String magnetUri, {String? savePath}) async {
|
||
try {
|
||
final infoHash = await TorrentPlatformService.addTorrent(
|
||
magnetUri: magnetUri,
|
||
savePath: savePath,
|
||
);
|
||
await refreshDownloads(); // Обновляем список
|
||
return infoHash;
|
||
} catch (e) {
|
||
_setError(e.toString());
|
||
return null;
|
||
}
|
||
}
|
||
|
||
/// Форматировать скорость
|
||
String formatSpeed(int bytesPerSecond) {
|
||
if (bytesPerSecond < 1024) return '${bytesPerSecond}B/s';
|
||
if (bytesPerSecond < 1024 * 1024) return '${(bytesPerSecond / 1024).toStringAsFixed(1)}KB/s';
|
||
return '${(bytesPerSecond / (1024 * 1024)).toStringAsFixed(1)}MB/s';
|
||
}
|
||
|
||
/// Форматировать продолжительность
|
||
String formatDuration(Duration duration) {
|
||
final hours = duration.inHours;
|
||
final minutes = duration.inMinutes.remainder(60);
|
||
final seconds = duration.inSeconds.remainder(60);
|
||
|
||
if (hours > 0) {
|
||
return '${hours}ч ${minutes}м ${seconds}с';
|
||
} else if (minutes > 0) {
|
||
return '${minutes}м ${seconds}с';
|
||
} else {
|
||
return '${seconds}с';
|
||
}
|
||
}
|
||
|
||
void _setLoading(bool loading) {
|
||
_isLoading = loading;
|
||
notifyListeners();
|
||
}
|
||
|
||
void _setError(String? error, [String? stackTrace]) {
|
||
_error = error;
|
||
_stackTrace = stackTrace;
|
||
notifyListeners();
|
||
}
|
||
} |