From b3aa8e095cc09e8a4cd4d389aabf19ac5d56ccf1 Mon Sep 17 00:00:00 2001 From: SquidSpirit Date: Thu, 10 Jul 2025 20:30:26 +0800 Subject: [PATCH] MCSI-2 refactor: move selected game version to installation bloc --- .../adapter/presentation/installation_state.dart | 6 +++++- lib/main/framework/ui/basic_configuration_tab.dart | 2 +- .../framework/ui/minecraft_server_installer.dart | 6 ++++-- lib/main/framework/ui/path_browsing_field.dart | 1 + lib/vanilla/adapter/presentation/vanilla_bloc.dart | 14 ++++++++------ .../adapter/presentation/vanilla_state.dart | 7 ------- .../framework/ui/game_version_dropdown.dart | 7 ++++--- 7 files changed, 23 insertions(+), 20 deletions(-) diff --git a/lib/main/adapter/presentation/installation_state.dart b/lib/main/adapter/presentation/installation_state.dart index c9767a6..9eb4d55 100644 --- a/lib/main/adapter/presentation/installation_state.dart +++ b/lib/main/adapter/presentation/installation_state.dart @@ -31,5 +31,9 @@ class InstallationState with EquatableMixin { savePath: savePath ?? this.savePath, ); - bool get canStartToInstall => gameVersion != null && savePath != null && savePath!.isNotEmpty; + bool get isGameVersionSelected => gameVersion != null; + + bool get isSavePathSelected => savePath != null && savePath!.isNotEmpty; + + bool get canStartToInstall => isGameVersionSelected && isSavePathSelected; } diff --git a/lib/main/framework/ui/basic_configuration_tab.dart b/lib/main/framework/ui/basic_configuration_tab.dart index 4f6909a..2e1b07e 100644 --- a/lib/main/framework/ui/basic_configuration_tab.dart +++ b/lib/main/framework/ui/basic_configuration_tab.dart @@ -39,7 +39,7 @@ class _BasicConfigurationTabState extends State { const Gap(32), ElevatedButton.icon( style: ElevatedButton.styleFrom(shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(4))), - onPressed: state.isGameVersionSelected ? _downloadServerFile : null, + onPressed: context.watch().state.isGameVersionSelected ? _downloadServerFile : null, icon: const Icon(Icons.download), label: const Padding( padding: EdgeInsets.symmetric(vertical: 12), diff --git a/lib/main/framework/ui/minecraft_server_installer.dart b/lib/main/framework/ui/minecraft_server_installer.dart index 3e861c1..c1ae2bd 100644 --- a/lib/main/framework/ui/minecraft_server_installer.dart +++ b/lib/main/framework/ui/minecraft_server_installer.dart @@ -24,16 +24,18 @@ class MinecraftServerInstaller extends StatelessWidget { final getGameVersionListUseCase = GetGameVersionListUseCase(gameVersionRepository); final downloadServerFileUseCase = DownloadServerFileUseCase(gameVersionRepository); + final installationBloc = InstallationBloc(); + return MaterialApp( title: 'Minecraft Server Installer', theme: ThemeData.light().copyWith(colorScheme: ColorScheme.fromSeed(seedColor: Colors.blue.shade900)), home: MultiBlocProvider( providers: [ + BlocProvider.value(value: installationBloc), BlocProvider( - create: (_) => VanillaBloc(getGameVersionListUseCase, downloadServerFileUseCase) + create: (_) => VanillaBloc(installationBloc, getGameVersionListUseCase, downloadServerFileUseCase) ..add(VanillaGameVersionListLoadedEvent()), ), - BlocProvider(create: (_) => InstallationBloc()) ], child: Scaffold( body: BlocConsumer( diff --git a/lib/main/framework/ui/path_browsing_field.dart b/lib/main/framework/ui/path_browsing_field.dart index 6ef5727..eb43b10 100644 --- a/lib/main/framework/ui/path_browsing_field.dart +++ b/lib/main/framework/ui/path_browsing_field.dart @@ -36,6 +36,7 @@ class _PathBrowsingFieldState extends State { child: TextField( controller: _textEditingController, readOnly: true, + canRequestFocus: false, decoration: InputDecoration( border: OutlineInputBorder(borderRadius: BorderRadius.circular(4)), label: const Text('${Strings.fieldPath} *'), diff --git a/lib/vanilla/adapter/presentation/vanilla_bloc.dart b/lib/vanilla/adapter/presentation/vanilla_bloc.dart index 8e92690..6d7f317 100644 --- a/lib/vanilla/adapter/presentation/vanilla_bloc.dart +++ b/lib/vanilla/adapter/presentation/vanilla_bloc.dart @@ -1,4 +1,5 @@ import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:minecraft_server_installer/main/adapter/presentation/installation_bloc.dart'; import 'package:minecraft_server_installer/main/constants.dart'; import 'package:minecraft_server_installer/vanilla/adapter/presentation/game_version_view_model.dart'; import 'package:minecraft_server_installer/vanilla/adapter/presentation/vanilla_state.dart'; @@ -7,10 +8,15 @@ import 'package:minecraft_server_installer/vanilla/application/use_case/get_game import 'package:path/path.dart' as path; class VanillaBloc extends Bloc { + final InstallationBloc _installationBloc; final GetGameVersionListUseCase _getGameVersionListUseCase; final DownloadServerFileUseCase _downloadServerFileUseCase; - VanillaBloc(this._getGameVersionListUseCase, this._downloadServerFileUseCase) : super(const VanillaState.empty()) { + VanillaBloc( + this._installationBloc, + this._getGameVersionListUseCase, + this._downloadServerFileUseCase, + ) : super(const VanillaState.empty()) { on((_, emit) async { try { final gameVersions = await _getGameVersionListUseCase(); @@ -24,12 +30,8 @@ class VanillaBloc extends Bloc { } }); - on((event, emit) { - emit(state.copyWith(selectedGameVersion: event.gameVersion)); - }); - on((event, emit) async { - final gameVersion = state.selectedGameVersion; + final gameVersion = _installationBloc.state.gameVersion; if (gameVersion == null) { return; } diff --git a/lib/vanilla/adapter/presentation/vanilla_state.dart b/lib/vanilla/adapter/presentation/vanilla_state.dart index f0185b2..697c4a4 100644 --- a/lib/vanilla/adapter/presentation/vanilla_state.dart +++ b/lib/vanilla/adapter/presentation/vanilla_state.dart @@ -5,13 +5,11 @@ class VanillaState with EquatableMixin { final bool isLocked; final double downloadProgress; final List gameVersions; - final GameVersionViewModel? selectedGameVersion; const VanillaState({ required this.isLocked, required this.downloadProgress, required this.gameVersions, - required this.selectedGameVersion, }); const VanillaState.empty() @@ -19,7 +17,6 @@ class VanillaState with EquatableMixin { isLocked: false, downloadProgress: 0, gameVersions: const [], - selectedGameVersion: null, ); @override @@ -27,11 +24,8 @@ class VanillaState with EquatableMixin { isLocked, downloadProgress, gameVersions, - selectedGameVersion, ]; - bool get isGameVersionSelected => selectedGameVersion != null; - bool get isDownloading => downloadProgress > 0 && downloadProgress < 1; VanillaState copyWith({ @@ -44,6 +38,5 @@ class VanillaState with EquatableMixin { isLocked: isLocked ?? this.isLocked, downloadProgress: downloadProgress ?? this.downloadProgress, gameVersions: gameVersions ?? this.gameVersions, - selectedGameVersion: selectedGameVersion ?? this.selectedGameVersion, ); } diff --git a/lib/vanilla/framework/ui/game_version_dropdown.dart b/lib/vanilla/framework/ui/game_version_dropdown.dart index 1c03072..7590b8c 100644 --- a/lib/vanilla/framework/ui/game_version_dropdown.dart +++ b/lib/vanilla/framework/ui/game_version_dropdown.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:minecraft_server_installer/main/adapter/presentation/installation_bloc.dart'; import 'package:minecraft_server_installer/main/framework/ui/strings.dart'; import 'package:minecraft_server_installer/vanilla/adapter/presentation/vanilla_bloc.dart'; import 'package:minecraft_server_installer/vanilla/adapter/presentation/game_version_view_model.dart'; @@ -11,15 +12,15 @@ class GameVersionDropdown extends StatelessWidget { @override Widget build(BuildContext context) => BlocConsumer( listener: (_, __) {}, - builder: (_, state) => DropdownMenu( - initialSelection: state.selectedGameVersion, + builder: (_, state) => DropdownMenu( + initialSelection: context.read().state.gameVersion, enabled: state.gameVersions.isNotEmpty, requestFocusOnTap: false, expandedInsets: EdgeInsets.zero, label: const Text('${Strings.fieldGameVersion} *'), onSelected: (value) { if (value != null) { - context.read().add(VanillaGameVersionSelectedEvent(value)); + context.read().add(InstallationConfigurationUpdatedEvent(gameVersion: value)); } }, dropdownMenuEntries: state.gameVersions