mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
feat(ui): add fallback when no layers exist
This commit is contained in:
parent
2baa33730a
commit
eb36e834b2
@ -1558,7 +1558,8 @@
|
|||||||
"globalInitialImageLayer": "$t(controlLayers.globalInitialImage) $t(unifiedCanvas.layer)",
|
"globalInitialImageLayer": "$t(controlLayers.globalInitialImage) $t(unifiedCanvas.layer)",
|
||||||
"opacityFilter": "Opacity Filter",
|
"opacityFilter": "Opacity Filter",
|
||||||
"clearProcessor": "Clear Processor",
|
"clearProcessor": "Clear Processor",
|
||||||
"resetProcessor": "Reset Processor to Defaults"
|
"resetProcessor": "Reset Processor to Defaults",
|
||||||
|
"noLayersAdded": "No Layers Added"
|
||||||
},
|
},
|
||||||
"ui": {
|
"ui": {
|
||||||
"tabs": {
|
"tabs": {
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
import { Flex } from '@invoke-ai/ui-library';
|
import { Flex } from '@invoke-ai/ui-library';
|
||||||
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
||||||
import { useAppSelector } from 'app/store/storeHooks';
|
import { useAppSelector } from 'app/store/storeHooks';
|
||||||
|
import { IAINoContentFallback } from 'common/components/IAIImageFallback';
|
||||||
import ScrollableContent from 'common/components/OverlayScrollbars/ScrollableContent';
|
import ScrollableContent from 'common/components/OverlayScrollbars/ScrollableContent';
|
||||||
import { AddLayerButton } from 'features/controlLayers/components/AddLayerButton';
|
import { AddLayerButton } from 'features/controlLayers/components/AddLayerButton';
|
||||||
import { CALayer } from 'features/controlLayers/components/CALayer/CALayer';
|
import { CALayer } from 'features/controlLayers/components/CALayer/CALayer';
|
||||||
@ -13,6 +14,7 @@ import { isRenderableLayer, selectControlLayersSlice } from 'features/controlLay
|
|||||||
import type { Layer } from 'features/controlLayers/store/types';
|
import type { Layer } from 'features/controlLayers/store/types';
|
||||||
import { partition } from 'lodash-es';
|
import { partition } from 'lodash-es';
|
||||||
import { memo } from 'react';
|
import { memo } from 'react';
|
||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
const selectLayerIdTypePairs = createMemoizedSelector(selectControlLayersSlice, (controlLayers) => {
|
const selectLayerIdTypePairs = createMemoizedSelector(selectControlLayersSlice, (controlLayers) => {
|
||||||
const [renderableLayers, ipAdapterLayers] = partition(controlLayers.present.layers, isRenderableLayer);
|
const [renderableLayers, ipAdapterLayers] = partition(controlLayers.present.layers, isRenderableLayer);
|
||||||
@ -20,6 +22,7 @@ const selectLayerIdTypePairs = createMemoizedSelector(selectControlLayersSlice,
|
|||||||
});
|
});
|
||||||
|
|
||||||
export const ControlLayersPanelContent = memo(() => {
|
export const ControlLayersPanelContent = memo(() => {
|
||||||
|
const { t } = useTranslation();
|
||||||
const layerIdTypePairs = useAppSelector(selectLayerIdTypePairs);
|
const layerIdTypePairs = useAppSelector(selectLayerIdTypePairs);
|
||||||
return (
|
return (
|
||||||
<Flex flexDir="column" gap={2} w="full" h="full">
|
<Flex flexDir="column" gap={2} w="full" h="full">
|
||||||
@ -27,6 +30,7 @@ export const ControlLayersPanelContent = memo(() => {
|
|||||||
<AddLayerButton />
|
<AddLayerButton />
|
||||||
<DeleteAllLayersButton />
|
<DeleteAllLayersButton />
|
||||||
</Flex>
|
</Flex>
|
||||||
|
{layerIdTypePairs.length > 0 && (
|
||||||
<ScrollableContent>
|
<ScrollableContent>
|
||||||
<Flex flexDir="column" gap={2}>
|
<Flex flexDir="column" gap={2}>
|
||||||
{layerIdTypePairs.map(({ id, type }) => (
|
{layerIdTypePairs.map(({ id, type }) => (
|
||||||
@ -34,6 +38,8 @@ export const ControlLayersPanelContent = memo(() => {
|
|||||||
))}
|
))}
|
||||||
</Flex>
|
</Flex>
|
||||||
</ScrollableContent>
|
</ScrollableContent>
|
||||||
|
)}
|
||||||
|
{layerIdTypePairs.length === 0 && <IAINoContentFallback icon={null} label={t('controlLayers.noLayersAdded')} />}
|
||||||
</Flex>
|
</Flex>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
@ -40,6 +40,7 @@ import type {
|
|||||||
VectorMaskRect,
|
VectorMaskRect,
|
||||||
} from 'features/controlLayers/store/types';
|
} from 'features/controlLayers/store/types';
|
||||||
import { getLayerBboxFast, getLayerBboxPixels } from 'features/controlLayers/util/bbox';
|
import { getLayerBboxFast, getLayerBboxPixels } from 'features/controlLayers/util/bbox';
|
||||||
|
import { t } from 'i18next';
|
||||||
import Konva from 'konva';
|
import Konva from 'konva';
|
||||||
import type { IRect, Vector2d } from 'konva/lib/types';
|
import type { IRect, Vector2d } from 'konva/lib/types';
|
||||||
import { debounce } from 'lodash-es';
|
import { debounce } from 'lodash-es';
|
||||||
@ -819,7 +820,7 @@ const createNoLayersMessageLayer = (stage: Konva.Stage): Konva.Layer => {
|
|||||||
y: 0,
|
y: 0,
|
||||||
align: 'center',
|
align: 'center',
|
||||||
verticalAlign: 'middle',
|
verticalAlign: 'middle',
|
||||||
text: 'No Layers Added',
|
text: t('controlLayers.noLayersAdded'),
|
||||||
fontFamily: '"Inter Variable", sans-serif',
|
fontFamily: '"Inter Variable", sans-serif',
|
||||||
fontStyle: '600',
|
fontStyle: '600',
|
||||||
fill: 'white',
|
fill: 'white',
|
||||||
|
Loading…
Reference in New Issue
Block a user