import 'package:riverpod_annotation/riverpod_annotation.dart'; import '../../../../backend/api/commands.dart' as commands; import '../../../../backend/transfer/model.dart'; part 'transfers_controller.g.dart'; @riverpod class TransfersController extends _$TransfersController { @override Future> build() async { return commands.getTransfers(); } Future refresh() async { state = const AsyncLoading(); state = await AsyncValue.guard(commands.getTransfers); } void updateProgress(String id, double currentBytes) { final current = state.asData?.value; if (current == null || current.isEmpty) { return; } final normalized = currentBytes < 0 ? 0.0 : currentBytes; var changed = false; final next = current .map((item) { if (item.id != id) { return item; } if ((item.progress - normalized).abs() < 0.001) { return item; } changed = true; return Transfer( id: item.id, createTime: item.createTime, sender: item.sender, senderIp: item.senderIp, fileName: item.fileName, fileSize: item.fileSize, savePath: item.savePath, status: item.status, type: item.type, contentType: item.contentType, text: item.text, errorMsg: item.errorMsg, token: item.token, progress: normalized, lastReadTime: item.lastReadTime, speed: item.speed, ); }) .toList(growable: false); if (changed) { state = AsyncData(next); } } void upsertTransfer(Transfer transfer) { final current = state.asData?.value ?? const []; final index = current.indexWhere((item) => item.id == transfer.id); if (index < 0) { state = AsyncData([...current, transfer]); return; } final old = current[index]; if (old == transfer) { return; } final next = [...current]; next[index] = transfer; state = AsyncData(next); } void removeTransfer(String id) { final current = state.asData?.value; if (current == null || current.isEmpty) { return; } final next = current.where((item) => item.id != id).toList(growable: false); if (next.length != current.length) { state = AsyncData(next); } } void clearTransfersLocal() { state = const AsyncData([]); } Future cancel(String id) async { await commands.cancelTransfer(id: id); } Future accept(String id, String path) async { await commands.resolvePendingRequest(id: id, accept: true, path: path); } Future reject(String id) async { await commands.resolvePendingRequest(id: id, accept: false, path: ''); } Future delete(String id) async { await commands.deleteTransfer(id: id); } Future clearCompleted() async { final current = state.asData?.value ?? const []; final hasCompleted = current.any( (item) => item.status is TransferStatus_Completed, ); if (!hasCompleted) { return; } await commands.clearTransfers(); } }