Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor ImportProfileModal to support mod list updates #1598

Merged
merged 4 commits into from
Jan 13, 2025

Conversation

anttimaki
Copy link
Collaborator

No description provided.

We want to access the preview step ASAP as this is where user is likely
to encounter problems with outdated or not loaded mod list.
Some call sites of the Vuex methods pass objects of wrong but
compatible type to the methods. TypeScript doesn't pick up on this as
the type support for the old Vuex version is non-existent. Extend the
argument types so some later changes to methods don't break when the
ExportMod object is passed.
The modal now shows a list of the known mods which can be installed, as
well as a list of the names of the unknown mods. If there's no known
mods, the import button is disabled. Option to cancel the import is
always shown, in case user wants to cancel after seeing the contents of
the profile.

The main reason for combining the modals is to make it easier to
provide an option for updating the mod list without leaving the modal.
This became important after the recent changes, as the splash screen no
longer guarantees that the mod list is loaded into Vuex.
SplashScreen no longer guarantees the online mod list has been loaded
into the memory, or the list might be fetched from IndexedDB and be
outdated. Profile import can't install mods that are not found in the
memory. To remedy the issue, allow users to trigger mod list update
directly from the profile import modal.
@anttimaki anttimaki force-pushed the splash-speedrun-pt4 branch from 349edb6 to bc97cde Compare January 7, 2025 11:53
@anttimaki anttimaki force-pushed the splash-speedrun-pt5 branch from 6c2348e to b8a5f50 Compare January 7, 2025 11:53
Base automatically changed from splash-speedrun-pt4 to develop January 13, 2025 07:46
@anttimaki anttimaki merged commit 5924f38 into develop Jan 13, 2025
5 checks passed
@anttimaki anttimaki deleted the splash-speedrun-pt5 branch January 13, 2025 07:48
| 'PROFILE_IS_BEING_IMPORTED'
= 'IMPORT_UPDATE_SELECTION';
= 'FILE_CODE_SELECTION';
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not an issue, just curious as to why the order changed? Seems somewhat unnecessary?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My idea was to fail early. As the step where the import process is most likely to "fail" is the preview step, I wanted to take the user there without having to e.g. create a new profile folder first.


if (mode === 'UPDATE') {
this.targetProfileName = this.activeProfileName;
get profileMods(): {known: ThunderstoreMod[], unknown: string[]} {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would be nicer as an interface IMO. Saves having to redefine the type across files.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure which files you refer to? The type isn't used elsewhere and doesn't need to be redefined even within the modal file.

@@ -317,32 +306,83 @@ export default class ImportProfileModal extends mixins(ProfilesMixin) {
<h2 class="modal-title">Packages to be installed</h2>
</template>
<template v-slot:body>
<OnlineModList :paged-mod-list="profileToOnlineMods" :read-only="true" />
<OnlineModList :paged-mod-list="profileMods.known" :read-only="true" />
<div v-if="!profileMods.known.length || profileMods.unknown.length" class="notification is-warning margin-top">
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can the length assertions include the number?
Aware !0 results in false, but I don't think it's overly readable. I'd prefer .length == 0 && ....

Writing for type safety is much nicer instead of relying on the conversion to boolean.

Applies to other v-if blocks too

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤷🏻

Some of the packages in the profile were not found on Thunderstore:
</p>

<p class="margin-top">{{ profileMods.unknown.join(", ") }}</p>
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Worth making computed? Moves logic out of the actual render.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤷🏻

Comment on lines +323 to +325
<p v-else class="margin-top">
Ensure the profile is intended for the currently selected game.
</p>
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is probably fairly useless as an indicator since the BepInEx/MelonLoader packages can be shared across games.

Would it be better UX if we have another modal step, and in that step we re-show the game name and ask if it's correct?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Granted, this was a 20% effort to get a 80% result.

IDK about the separate step. I kinda like the idea of having all the possible problems on the same step, and not having extra steps when no problems are detected, to keep the process simple. That being said, I was wondering if we could add the info about the targeted game into the r2x file? That way we could explicitly detect this issue (for new profiles anyway) and tell the user to change the game.

</span>
<span v-else-if="$store.state.tsMods.thunderstoreModListUpdateError">
Error updating the mod list:
{{ $store.state.tsMods.thunderstoreModListUpdateError }}.
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we have a similar concern here as with one of the previous PRs? Should we instead give the user the option to view the error in a separate error modal? Do they actually care about an inline variant of the message?

Generally the error modal is a fixed place for "something went wrong, we're informing you on what it is".
The actual purpose of this part is to allow the user to try again.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The way I see it is that the user might want to proceed with the import even if the update fails. Opening the error modal would prevent them from continuing where they left off, which to me is more awkward than the inline error text. I'm not completely against changing this though, if it's seen as an improvement.

class="button is-danger"
@click="closeModal"
>
Cancel import
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think Cancel alone is fine? Not overly fussed.

We don't usually offer "Cancel" actions though. It's expected that the user would just click off the modal. Might be nice to make it consistent in other places if we're going to start doing this.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤷🏻

anttimaki added a commit that referenced this pull request Jan 20, 2025
- Explicitly check array lengths in conditional statements in template
- Add computed property for unknownProfileModNames
- Remove cancel button as they really aren't used elsewhere in the app
@anttimaki
Copy link
Collaborator Author

🤷🏻 = Changes implemented in #1622

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants