diff --git a/src/meson.build b/src/meson.build index dd790a1..b45e687 100644 --- a/src/meson.build +++ b/src/meson.build @@ -68,6 +68,7 @@ sources = files( 'models/releases/basic.vala', 'models/releases/github-action.vala', + 'models/releases/upgrade.vala', 'models/releases/steamtinkerlaunch.vala', 'utils/filesystem.vala', diff --git a/src/models/release.vala b/src/models/release.vala index 85ac6d5..63c4c43 100644 --- a/src/models/release.vala +++ b/src/models/release.vala @@ -40,5 +40,55 @@ namespace ProtonPlus.Models { break; } } + + public async bool install () { + var busy_upgrading = state == State.BUSY_UPGRADING; + + if (!busy_upgrading) + state = State.BUSY_INSTALLING; + + // Attempt the installation. + var install_success = yield _start_install (); + + if (install_success && !busy_upgrading) + send_message (_("The installation of %s is complete.").printf (title)); + else { + // Attempt to clean up any leftover files and symlinks, + // but don't erase the user's STL configuration files. + yield remove (false); // Refreshes install state too. + + if (!busy_upgrading) + send_message (_("An unexpected error occurred while installing %s.").printf (title)); + } + + refresh_state (); // Force UI state refresh. + + return install_success; + } + + protected abstract async bool _start_install (); + + public async bool remove (Variant variant) { + var busy_upgrading_or_instaling = state == State.BUSY_UPGRADING || state == State.BUSY_INSTALLING; + + if (!busy_upgrading_or_instaling) + state = State.BUSY_REMOVING; + + // Attempt the removal. + var remove_success = yield _start_remove (variant); + + if (remove_success && !busy_upgrading_or_instaling) + send_message (_("The removal of %s is complete.").printf (title)); + else if (!busy_upgrading_or_instaling) + send_message (_("An unexpected error occurred while removing %s.").printf (title)); + + refresh_state (); // Force UI state refresh. + + return remove_success; + } + + protected abstract async bool _start_remove (Variant variant); + + protected abstract void refresh_state (); } } \ No newline at end of file diff --git a/src/models/releases/basic.vala b/src/models/releases/basic.vala index d93ef75..6daf4be 100644 --- a/src/models/releases/basic.vala +++ b/src/models/releases/basic.vala @@ -28,33 +28,13 @@ namespace ProtonPlus.Models.Releases { install_location = runner.group.launcher.directory + runner.group.directory + "/" + runner.get_directory_name (title); } - protected void refresh_state () { + protected override void refresh_state () { canceled = false; state = FileUtils.test (install_location, FileTest.IS_DIR) ? State.UP_TO_DATE : State.NOT_INSTALLED; } - public async bool install () { - state = State.BUSY_INSTALLING; - - var install_success = yield _start_install (); - - if (canceled) - send_message (_("The installation of %s was canceled.").printf (title)); - else if (install_success) - send_message (_("The installation of %s is complete.").printf (title)); - else - send_message (_("An unexpected error occurred while installing %s.").printf (title)); - - if (canceled || !install_success) - yield remove (); - - refresh_state (); - - return true; - } - - protected virtual async bool _start_install () { + protected override async bool _start_install () { send_message (_("Downloading...")); string path = runner.group.launcher.directory + runner.group.directory + "/" + title + ".tar.gz"; @@ -92,25 +72,7 @@ namespace ProtonPlus.Models.Releases { return true; } - public async bool remove () { - var busy_installing = state == State.BUSY_INSTALLING; - - if (!busy_installing) - state = State.BUSY_REMOVING; - - var remove_success = yield _start_remove (); - - if (remove_success && !busy_installing) - send_message (_("The removal of %s is complete.").printf (title)); - else if (!busy_installing) - send_message (_("An unexpected error occurred while removing %s.").printf (title)); - - refresh_state (); - - return true; - } - - protected virtual async bool _start_remove () { + protected override async bool _start_remove (Variant variant) { send_message (_("Deleting...")); var deleted = yield Utils.Filesystem.delete_directory (install_location); diff --git a/src/models/releases/steamtinkerlaunch.vala b/src/models/releases/steamtinkerlaunch.vala index 54f7147..5bcb35a 100644 --- a/src/models/releases/steamtinkerlaunch.vala +++ b/src/models/releases/steamtinkerlaunch.vala @@ -1,5 +1,5 @@ namespace ProtonPlus.Models.Releases { - public class SteamTinkerLaunch : Release { + public class SteamTinkerLaunch : Upgrade { string home_location { get; set; } string compat_location { get; set; } string parent_location { get; set; } @@ -136,7 +136,30 @@ namespace ProtonPlus.Models.Releases { } } - void refresh_state () { + void write_installation_metadata (string meta_location) { + Utils.Filesystem.create_file (meta_location, @"$latest_date:$latest_hash"); + } + + public bool detect_external_locations () { + if (external_locations.length () > 0) + external_locations = new List (); + + var location = @"$home_location/SteamTinkerLaunch"; + if (FileUtils.test (location, FileTest.IS_DIR)) + external_locations.append (location); + + location = Environment.get_home_dir () + "/stl"; + if (!Utils.System.IS_STEAM_OS && FileUtils.test (location, FileTest.IS_DIR)) + external_locations.append (location); + + // Disabled for now, since we always erase base_location before installs. + // if (FileUtils.test (base_location, FileTest.IS_DIR) && !FileUtils.test (meta_location, FileTest.IS_REGULAR)) + // external_locations.append (base_location); + + return external_locations.length () > 0; + } + + protected override void refresh_state () { // Update the ProtonPlus UI state variables. // NOTE: We treat a non-executable binary as a "broken installation". var base_location_exists = FileUtils.test (base_location, FileTest.IS_DIR); @@ -190,55 +213,7 @@ namespace ProtonPlus.Models.Releases { state = !installed ? State.NOT_INSTALLED : updated ? State.UP_TO_DATE : State.UPDATE_AVAILABLE; } - void write_installation_metadata (string meta_location) { - Utils.Filesystem.create_file (meta_location, @"$latest_date:$latest_hash"); - } - - public bool detect_external_locations () { - if (external_locations.length () > 0) - external_locations = new List (); - - var location = @"$home_location/SteamTinkerLaunch"; - if (FileUtils.test (location, FileTest.IS_DIR)) - external_locations.append (location); - - location = Environment.get_home_dir () + "/stl"; - if (!Utils.System.IS_STEAM_OS && FileUtils.test (location, FileTest.IS_DIR)) - external_locations.append (location); - - // Disabled for now, since we always erase base_location before installs. - // if (FileUtils.test (base_location, FileTest.IS_DIR) && !FileUtils.test (meta_location, FileTest.IS_REGULAR)) - // external_locations.append (base_location); - - return external_locations.length () > 0; - } - - public async bool install () { - var busy_upgrading = state == State.BUSY_UPGRADING; - - if (!busy_upgrading) - state = State.BUSY_INSTALLING; - - // Attempt the installation. - var install_success = yield _start_install (); - - if (install_success && !busy_upgrading) - send_message (_("The installation of %s is complete.").printf (title)); - else { - // Attempt to clean up any leftover files and symlinks, - // but don't erase the user's STL configuration files. - yield remove (false); // Refreshes install state too. - - if (!busy_upgrading) - send_message (_("An unexpected error occurred while installing %s.").printf (title)); - } - - refresh_state (); // Force UI state refresh. - - return install_success; - } - - async bool _start_install () { + protected async override bool _start_install () { if (Utils.System.check_dependency ("steamtinkerlaunch")) Utils.System.run_command ("steamtinkerlaunch compat del"); @@ -334,53 +309,17 @@ namespace ProtonPlus.Models.Releases { return true; } - public async bool upgrade () { - state = State.BUSY_UPGRADING; + // Variant (delete_config, user_request) + protected override async bool _start_remove (Variant variant) { + bool delete_config = false; + bool user_request = false; - var upgrade_success = yield _start_upgrade (); - - if (upgrade_success) - send_message (_("The upgrade of %s is complete.").printf (title)); - else - send_message (_("An unexpected error occurred while upgrading %s.")); - - return upgrade_success; - } + var iterator = variant.iterator (); + if (variant.n_children () >= 1) + iterator.next ("b", &delete_config); + if (variant.n_children () == 2) + iterator.next ("b", &user_request); - async bool _start_upgrade () { - var remove_success = yield remove (false); - - if (!remove_success) - return false; - - var install_success = yield install (); - - if (!install_success) - return false; - - return true; - } - - public async bool remove (bool delete_config, bool user_request = false) { - var busy_upgrading_or_instaling = state == State.BUSY_UPGRADING || state == State.BUSY_INSTALLING; - - if (!busy_upgrading_or_instaling) - state = State.BUSY_REMOVING; - - // Attempt the removal. - var remove_success = yield _start_remove (delete_config, user_request); - - if (remove_success && !busy_upgrading_or_instaling) - send_message (_("The removal of %s is complete.").printf (title)); - else if (!busy_upgrading_or_instaling) - send_message (_("An unexpected error occurred while removing %s.").printf (title)); - - refresh_state (); // Force UI state refresh. - - return remove_success; - } - - async bool _start_remove (bool delete_config, bool user_request = false) { exec_stl_if_exists (binary_location, "compat del"); // NOTE: We check specific types to avoid deleting unexpected data. @@ -417,5 +356,19 @@ namespace ProtonPlus.Models.Releases { return true; } + + protected override async bool _start_upgrade () { + var remove_success = yield remove (false); + + if (!remove_success) + return false; + + var install_success = yield install (); + + if (!install_success) + return false; + + return true; + } } } \ No newline at end of file diff --git a/src/models/releases/upgrade.vala b/src/models/releases/upgrade.vala new file mode 100644 index 0000000..47171e7 --- /dev/null +++ b/src/models/releases/upgrade.vala @@ -0,0 +1,18 @@ +namespace ProtonPlus.Models.Releases { + public abstract class Upgrade : Release { + public async bool upgrade () { + state = State.BUSY_UPGRADING; + + var upgrade_success = yield _start_upgrade (); + + if (upgrade_success) + send_message (_("The upgrade of %s is complete.").printf (title)); + else + send_message (_("An unexpected error occurred while upgrading %s.")); + + return upgrade_success; + } + + protected abstract async bool _start_upgrade (); + } +} \ No newline at end of file diff --git a/src/widgets/release-rows/basic.vala b/src/widgets/release-rows/basic.vala index c65c261..eb27aa2 100644 --- a/src/widgets/release-rows/basic.vala +++ b/src/widgets/release-rows/basic.vala @@ -49,7 +49,7 @@ namespace ProtonPlus.Widgets.ReleaseRows { remove_dialog.present (); - release.remove.begin ((obj, res) => { + release.remove.begin ("", (obj, res) => { var success = release.remove.end (res); remove_dialog.done (success); diff --git a/src/widgets/release-rows/steamtinkerlaunch.vala b/src/widgets/release-rows/steamtinkerlaunch.vala index f7ea4e8..48c6dc3 100644 --- a/src/widgets/release-rows/steamtinkerlaunch.vala +++ b/src/widgets/release-rows/steamtinkerlaunch.vala @@ -69,7 +69,7 @@ namespace ProtonPlus.Widgets.ReleaseRows { remove_dialog.present (); - release.remove.begin (remove_check.get_active (), true, (obj, res) => { + release.remove.begin (new Variant ("(bb)", remove_check.get_active (), true), (obj, res) => { var success = release.remove.end (res); remove_dialog.done (success);