Update the button label in the dialog of an extension to show if the extension will be updated or (re)installed (#3777)

This commit is contained in:
Arthur Pacaud
2022-04-06 14:47:36 +02:00
committed by GitHub
parent a7df37a0dc
commit 5b8cdbbace
4 changed files with 76 additions and 7 deletions

View File

@@ -23,6 +23,7 @@ import { IconContainer } from '../../UI/IconContainer';
import { UserPublicProfileChip } from '../../UI/User/UserPublicProfileChip';
import RaisedButton from '../../UI/RaisedButton';
import Window from '../../Utils/Window';
import { useExtensionUpdate } from './UseExtensionUpdates';
const getTransformedDescription = (extensionHeader: ExtensionHeader) => {
if (
@@ -45,7 +46,7 @@ type Props = {|
onClose: () => void,
onInstall: () => Promise<void>,
onEdit?: () => void,
alreadyInstalled: boolean,
project: gdProject,
|};
const ExtensionInstallDialog = ({
@@ -54,8 +55,13 @@ const ExtensionInstallDialog = ({
onClose,
onInstall,
onEdit,
alreadyInstalled,
project,
}: Props) => {
const alreadyInstalled = project.hasEventsFunctionsExtensionNamed(
extensionShortHeader.name
);
const extensionUpdate = useExtensionUpdate(project, extensionShortHeader);
const [error, setError] = React.useState<?Error>(null);
const [
extensionHeader,
@@ -118,7 +124,11 @@ const ExtensionInstallDialog = ({
!isCompatible ? (
<Trans>Not compatible</Trans>
) : alreadyInstalled ? (
<Trans>Re-install/update</Trans>
extensionUpdate ? (
<Trans>Update</Trans>
) : (
<Trans>Re-install</Trans>
)
) : (
<Trans>Install in project</Trans>
)

View File

@@ -0,0 +1,61 @@
//@flow
import { diff } from 'semver/functions/diff';
import { enumerateEventsFunctionsExtensions } from '../../ProjectManager/EnumerateProjectItems';
import { ExtensionStoreContext } from './ExtensionStoreContext';
import { useContext, useMemo } from 'react';
import type { ExtensionShortHeader } from '../../Utils/GDevelopServices/Extension';
type UpdateType = 'patch' | 'minor' | 'major';
type UpdateMetadata = {|
type: UpdateType,
currentVersion: string,
newestVersion: string,
|};
type ExtensionUpdates = Map<string, UpdateMetadata>;
const getUpdateMetadataFromVersions = (
currentVersion: string,
newestVersion: string
): UpdateMetadata | null => {
try {
const versionDiff: UpdateType = diff(currentVersion, newestVersion);
if (['patch', 'minor', 'major'].includes(versionDiff)) {
return {
type: versionDiff,
currentVersion,
newestVersion,
};
}
} catch {
// An error will be thrown here only if the version is not in semver.
// Simply compare the strings for such extensions.
// Note that this is an edge case, the extension repository enforces semver, so this
// is only for local extensions that do not respect the best practices.
if (currentVersion !== newestVersion) {
return {
// Use minor as it is the most neutral option
type: 'minor',
currentVersion,
newestVersion,
};
}
}
return null;
};
export const useExtensionUpdate = (
project: gdProject,
extension: ExtensionShortHeader
): UpdateMetadata | null => {
return useMemo<UpdateMetadata | null>(
() =>
project.hasEventsFunctionsExtensionNamed(extension.name)
? getUpdateMetadataFromVersions(
project.getEventsFunctionsExtension(extension.name).getVersion(),
extension.version
)
: null,
[project, extension]
);
};

View File

@@ -121,11 +121,9 @@ export const ExtensionStore = ({
</ResponsiveWindowMeasurer>
{!!selectedExtensionShortHeader && (
<ExtensionInstallDialog
project={project}
isInstalling={isInstalling}
extensionShortHeader={selectedExtensionShortHeader}
alreadyInstalled={project.hasEventsFunctionsExtensionNamed(
selectedExtensionShortHeader.name
)}
onInstall={async () => {
const wasInstalled = await onInstall(selectedExtensionShortHeader);
if (wasInstalled) setSelectedExtensionShortHeader(null);

View File

@@ -50,7 +50,7 @@ function InstalledExtensionDetails({
<I18n>
{({ i18n }) => (
<ExtensionInstallDialog
alreadyInstalled
project={project}
isInstalling={isInstalling}
onClose={onClose}
onInstall={() => installOrUpdateExtension(i18n)}