mirror of
https://github.com/4ian/GDevelop.git
synced 2025-10-15 10:19:04 +00:00
Display more info on missing action/condition placeholder (#5415)
This commit is contained in:
@@ -33,6 +33,7 @@ type ExtensionStoreState = {|
|
||||
setChosenCategory: string => void,
|
||||
extensionShortHeadersByName: { [name: string]: ExtensionShortHeader },
|
||||
filtersState: FiltersState,
|
||||
hasExtensionNamed: (extensionName: string) => boolean,
|
||||
|};
|
||||
|
||||
export const ExtensionStoreContext = React.createContext<ExtensionStoreState>({
|
||||
@@ -54,6 +55,7 @@ export const ExtensionStoreContext = React.createContext<ExtensionStoreState>({
|
||||
chosenCategory: null,
|
||||
setChosenCategory: () => {},
|
||||
},
|
||||
hasExtensionNamed: () => false,
|
||||
});
|
||||
|
||||
type ExtensionStoreStateProviderProps = {|
|
||||
@@ -183,6 +185,13 @@ export const ExtensionStoreStateProvider = ({
|
||||
defaultFirstSearchItemIds: firstExtensionIds,
|
||||
});
|
||||
|
||||
const hasExtensionNamed = React.useCallback(
|
||||
(extensionName: string) => {
|
||||
return !!extensionShortHeadersByName[extensionName];
|
||||
},
|
||||
[extensionShortHeadersByName]
|
||||
);
|
||||
|
||||
const extensionStoreState = React.useMemo(
|
||||
() => ({
|
||||
searchResults,
|
||||
@@ -196,6 +205,7 @@ export const ExtensionStoreStateProvider = ({
|
||||
setSearchText,
|
||||
extensionShortHeadersByName,
|
||||
filtersState,
|
||||
hasExtensionNamed,
|
||||
}),
|
||||
[
|
||||
searchResults,
|
||||
@@ -208,6 +218,7 @@ export const ExtensionStoreStateProvider = ({
|
||||
extensionShortHeadersByName,
|
||||
filtersState,
|
||||
fetchExtensionsAndFilters,
|
||||
hasExtensionNamed,
|
||||
]
|
||||
);
|
||||
|
||||
|
@@ -39,6 +39,8 @@ import Tooltip from '@material-ui/core/Tooltip';
|
||||
import GDevelopThemeContext from '../../UI/Theme/GDevelopThemeContext';
|
||||
import { type EventsScope } from '../../InstructionOrExpression/EventsScope.flow';
|
||||
import { enumerateParametersUsableInExpressions } from '../ParameterFields/EnumerateFunctionParameters';
|
||||
import { getFunctionNameFromType } from '../../EventsFunctionsExtensionsLoader';
|
||||
import { ExtensionStoreContext } from '../../AssetStore/ExtensionStore/ExtensionStoreContext';
|
||||
|
||||
const gd: libGDevelop = global.gd;
|
||||
|
||||
@@ -128,6 +130,69 @@ const formatValue = ({
|
||||
? i18n._(t`Base layer`)
|
||||
: value;
|
||||
|
||||
const InstructionMissing = (props: {|
|
||||
instructionType: string,
|
||||
isCondition: boolean,
|
||||
|}) => {
|
||||
const { hasExtensionNamed } = React.useContext(ExtensionStoreContext);
|
||||
const { name, behaviorName, extensionName } = getFunctionNameFromType(
|
||||
props.instructionType
|
||||
);
|
||||
const extensionStoreMention = hasExtensionNamed(extensionName) ? (
|
||||
<Trans>Try installing it from the extension store.</Trans>
|
||||
) : (
|
||||
''
|
||||
);
|
||||
|
||||
const functionNode = <span className="function-name">{name}</span>;
|
||||
const behaviorNode = <span className="behavior-name">{behaviorName}</span>;
|
||||
const extensionNode = <span className="extension-name">{extensionName}</span>;
|
||||
|
||||
if (behaviorName) {
|
||||
if (props.isCondition) {
|
||||
return (
|
||||
<span className="instruction-missing">
|
||||
<Trans>
|
||||
{functionNode} condition on behavior {behaviorNode} from
|
||||
{extensionNode} extension is missing.
|
||||
</Trans>{' '}
|
||||
{extensionStoreMention}
|
||||
</span>
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
<span className="instruction-missing">
|
||||
<Trans>
|
||||
{functionNode} action on behavior {behaviorNode} from
|
||||
{extensionNode} extension is missing.
|
||||
</Trans>{' '}
|
||||
{extensionStoreMention}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
} else {
|
||||
if (props.isCondition) {
|
||||
return (
|
||||
<span className="instruction-missing">
|
||||
<Trans>
|
||||
{functionNode} condition from {extensionNode} extension is missing.
|
||||
</Trans>{' '}
|
||||
{extensionStoreMention}
|
||||
</span>
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
<span className="instruction-missing">
|
||||
<Trans>
|
||||
{functionNode} action from {extensionNode} extension is missing.
|
||||
</Trans>{' '}
|
||||
{extensionStoreMention}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const Instruction = (props: Props) => {
|
||||
const {
|
||||
instruction,
|
||||
@@ -187,6 +252,15 @@ const Instruction = (props: Props) => {
|
||||
parameterIndex >= 0 && parameterIndex < parametersCount;
|
||||
|
||||
if (!isParameter) {
|
||||
if (value === 'Unknown or unsupported instruction') {
|
||||
return (
|
||||
<InstructionMissing
|
||||
instructionType={instruction.getType()}
|
||||
isCondition={isCondition}
|
||||
key={`unknown-behavior-instruction-${i}`}
|
||||
/>
|
||||
);
|
||||
}
|
||||
return <span key={i}>{i === 0 ? capitalize(value) : value}</span>;
|
||||
}
|
||||
|
||||
|
@@ -119,6 +119,23 @@
|
||||
color: var(--event-sheet-instruction-parameter-number-color);
|
||||
}
|
||||
|
||||
.gd-events-sheet .instruction-missing {
|
||||
text-decoration: var(--event-sheet-instruction-parameter-error-color) underline wavy;
|
||||
}
|
||||
|
||||
.gd-events-sheet .instruction-missing .function-name {
|
||||
color: var(--event-sheet-instruction-parameter-error-color);
|
||||
font-weight: bold;
|
||||
}
|
||||
.gd-events-sheet .instruction-missing .behavior-name {
|
||||
color: var(--event-sheet-instruction-parameter-error-color);
|
||||
font-weight: bold;
|
||||
}
|
||||
.gd-events-sheet .instruction-missing .extension-name {
|
||||
user-select: all;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.gd-events-sheet .instruction-parameter.object,
|
||||
.gd-events-sheet .instruction-parameter.objectPtr,
|
||||
.gd-events-sheet .instruction-parameter.objectList,
|
||||
|
Reference in New Issue
Block a user