mirror of
https://github.com/4ian/GDevelop.git
synced 2025-10-15 10:19:04 +00:00
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:
@@ -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>
|
||||
)
|
||||
|
@@ -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]
|
||||
);
|
||||
};
|
@@ -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);
|
||||
|
@@ -50,7 +50,7 @@ function InstalledExtensionDetails({
|
||||
<I18n>
|
||||
{({ i18n }) => (
|
||||
<ExtensionInstallDialog
|
||||
alreadyInstalled
|
||||
project={project}
|
||||
isInstalling={isInstalling}
|
||||
onClose={onClose}
|
||||
onInstall={() => installOrUpdateExtension(i18n)}
|
||||
|
Reference in New Issue
Block a user