import 'dart:async'; import 'package:file_picker/file_picker.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:moonwell_launcher/app/home_screen/bloc/home_screen_model.dart'; import 'package:moonwell_launcher/features/downloader/application/download_manager.dart'; import 'package:moonwell_launcher/features/downloader/domain/entities/download_progress.dart'; import 'package:moonwell_launcher/features/downloader/domain/entities/download_request.dart'; import 'package:moonwell_launcher/features/preferences/domain/repositories/preferences_repository.dart'; import 'package:rxdart/rxdart.dart'; part 'home_screen_event.dart'; part 'home_screen_state.dart'; const _downloadId = 'client'; class HomeScreenBloc extends Bloc { final DownloadManager _downloadManager; final PreferencesRepository _preferencesRepository; StreamSubscription? _downloadProgressSubscription; HomeScreenBloc({ required DownloadManager downloadManager, required PreferencesRepository preferencesRepository, }) : _downloadManager = downloadManager, _preferencesRepository = preferencesRepository, super(HomeScreenInitialState(model: HomeScreenModel.initial())) { _setupHandlers(); add(HomeScreenLoad()); } void _setupHandlers() { on(_onHomeScreenLoad); on(_onHomeScreenDownloadRequested); on((event, emit) { // _downloadManager.pauseDownload(); // emit(HomeScreenDownloadPausedState()); }); on( _onHomeScreenDownloadProgressUpdated, transformer: (events, mapper) => events.throttleTime(const Duration(seconds: 2)).switchMap(mapper), ); } Future _onHomeScreenLoad( HomeScreenLoad event, Emitter emit, ) async { final outputDir = await _preferencesRepository.getOutputDir(); emit( HomeScreenReadyToDownloadState( model: state.model.copyWith(outputPath: outputDir), ), ); } Future _onHomeScreenDownloadRequested( HomeScreenDownloadRequested event, Emitter emit, ) async { if (state.model.outputPath == null) { final directory = await FilePicker.platform.getDirectoryPath( dialogTitle: 'Please select installation directory', ); if (directory == null) { return; } await _preferencesRepository.setOutputDir(Uri.directory(directory)); emit( HomeScreenReadyToDownloadState( model: state.model.copyWith(outputPath: Uri.directory(directory)), ), ); } _downloadProgressSubscription = _downloadManager .start( id: _downloadId, request: DownloadRequest( destinationPath: state.model.outputPath!.toFilePath(), ), ) .listen((progress) => add(HomeScreenDownloadProgressUpdated(progress))); } void _onHomeScreenDownloadProgressUpdated( HomeScreenDownloadProgressUpdated event, Emitter emit, ) { emit( HomeScreenDownloadingState( model: state.model.copyWith(progress: event.progress), ), ); } @override Future close() async { await _downloadProgressSubscription?.cancel(); await _downloadManager.cancel(_downloadId); return super.close(); } }