Files
InvokeAI/invokeai/frontend/web/src/features/controlLayers/hooks/useEntityTitle.ts
psychedelicious dd7d4da5e3 feat(ui): normalize all actions to accept an entityIdentifier
Previously, canvas actions specific to an entity type only needed the id of that entity type. This allowed you to pass in the id of an entity of the wrong type.

All actions for a specific entity now take a full entity identifier, and the entity identifier type can be narrowed.

`selectEntity` and `selectEntityOrThrow` now need a full entity identifier, and narrow their return values to a specific entity type _if_ the entity identifier is narrowed.

The types for canvas entities are updated with optional type parameters for this purpose.

All reducers, actions and components have been updated.
2024-09-06 22:56:24 +10:00

54 lines
2.0 KiB
TypeScript

import { createSelector } from '@reduxjs/toolkit';
import { useAppSelector } from 'app/store/storeHooks';
import { useEntityObjectCount } from 'features/controlLayers/hooks/useEntityObjectCount';
import { selectCanvasV2Slice, selectEntity } from 'features/controlLayers/store/selectors';
import type { CanvasEntityIdentifier } from 'features/controlLayers/store/types';
import { useMemo } from 'react';
import { useTranslation } from 'react-i18next';
import { assert } from 'tsafe';
const createSelectName = (entityIdentifier: CanvasEntityIdentifier) =>
createSelector(selectCanvasV2Slice, (canvasV2) => {
const entity = selectEntity(canvasV2, entityIdentifier);
if (!entity) {
return null;
}
return entity.name;
});
export const useEntityTitle = (entityIdentifier: CanvasEntityIdentifier) => {
const { t } = useTranslation();
const selectName = useMemo(() => createSelectName(entityIdentifier), [entityIdentifier]);
const name = useAppSelector(selectName);
const objectCount = useEntityObjectCount(entityIdentifier);
const title = useMemo(() => {
if (name) {
return name;
}
const parts: string[] = [];
if (entityIdentifier.type === 'inpaint_mask') {
parts.push(t('controlLayers.inpaintMask', { count: 1 }));
} else if (entityIdentifier.type === 'control_layer') {
parts.push(t('controlLayers.controlLayer', { count: 1 }));
} else if (entityIdentifier.type === 'raster_layer') {
parts.push(t('controlLayers.rasterLayer', { count: 1 }));
} else if (entityIdentifier.type === 'ip_adapter') {
parts.push(t('common.ipAdapter', { count: 1 }));
} else if (entityIdentifier.type === 'regional_guidance') {
parts.push(t('controlLayers.regionalGuidance', { count: 1 }));
} else {
assert(false, 'Unexpected entity type');
}
if (objectCount > 0) {
parts.push(`(${objectCount})`);
}
return parts.join(' ');
}, [entityIdentifier.type, name, objectCount, t]);
return title;
};