feat(peer): remove downloaded game files safely
Downloaded but uninstalled games can still occupy significant disk space. Add a separate removal path for that state instead of overloading uninstall, which is reserved for deleting only `local/` installs. The peer runtime now exposes `RemoveDownloadedGame` with matching lifecycle and active-operation events. The filesystem delete is intentionally strict: the id must be a catalog game and a single path component, the target must be a direct child of the configured game directory, the root must not be a symlink, it must have a regular root-level `version.ini`, and it must not contain `local/`, `.local.installing/`, or `.local.backup/`. Only then do we recursively remove the game root. The Tauri bridge exposes this as `remove_downloaded_game`, the frontend shows a matching danger action only for downloaded-but-uninstalled games, and a confirmation dialog warns that re-downloading can take a long time. Test Plan: - git diff --check - just fmt - RUSTC_WRAPPER= CARGO_BUILD_RUSTC_WRAPPER= just test - RUSTC_WRAPPER= CARGO_BUILD_RUSTC_WRAPPER= just clippy - RUSTC_WRAPPER= CARGO_BUILD_RUSTC_WRAPPER= just build Refs: user redesign nitpick about removing downloaded uninstalled games
This commit is contained in:
@@ -67,6 +67,7 @@ use crate::{
|
||||
handle_get_peer_count_command,
|
||||
handle_install_game_command,
|
||||
handle_list_games_command,
|
||||
handle_remove_downloaded_game_command,
|
||||
handle_set_game_dir_command,
|
||||
handle_uninstall_game_command,
|
||||
load_local_library,
|
||||
@@ -120,6 +121,12 @@ pub enum PeerEvent {
|
||||
UninstallGameFinished { id: String },
|
||||
/// Uninstall transaction has failed after rollback.
|
||||
UninstallGameFailed { id: String },
|
||||
/// Downloaded archive removal has started for an uninstalled game.
|
||||
RemoveDownloadedGameBegin { id: String },
|
||||
/// Downloaded archive removal has completed successfully.
|
||||
RemoveDownloadedGameFinished { id: String },
|
||||
/// Downloaded archive removal has failed before deleting the game root.
|
||||
RemoveDownloadedGameFailed { id: String },
|
||||
/// No peers have the requested game.
|
||||
NoPeersHaveGame { id: String },
|
||||
/// A peer has connected.
|
||||
@@ -187,6 +194,8 @@ pub enum ActiveOperationKind {
|
||||
Updating,
|
||||
/// Removing an existing `local/` install.
|
||||
Uninstalling,
|
||||
/// Removing downloaded archive files for an uninstalled game.
|
||||
RemovingDownload,
|
||||
}
|
||||
|
||||
/// Commands sent to the peer system from the UI.
|
||||
@@ -213,6 +222,8 @@ pub enum PeerCommand {
|
||||
InstallGame { id: String },
|
||||
/// Remove only the `local/` install for a game.
|
||||
UninstallGame { id: String },
|
||||
/// Remove downloaded archive files for an uninstalled game.
|
||||
RemoveDownloadedGame { id: String },
|
||||
/// Set the local game directory.
|
||||
SetGameDir(PathBuf),
|
||||
/// Request the current peer count.
|
||||
@@ -394,6 +405,9 @@ async fn handle_peer_commands(
|
||||
PeerCommand::UninstallGame { id } => {
|
||||
handle_uninstall_game_command(ctx, tx_notify_ui, id).await;
|
||||
}
|
||||
PeerCommand::RemoveDownloadedGame { id } => {
|
||||
handle_remove_downloaded_game_command(ctx, tx_notify_ui, id).await;
|
||||
}
|
||||
PeerCommand::SetGameDir(game_dir) => {
|
||||
handle_set_game_dir_command(ctx, tx_notify_ui, game_dir).await;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user