mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
UI more pr feedback
This commit is contained in:
parent
41c3e73a3c
commit
1e547ef912
@ -1,11 +1,12 @@
|
|||||||
import { Badge, ConfirmationAlertDialog, Flex, IconButton, Text, useDisclosure } from '@invoke-ai/ui-library';
|
import { Badge, ConfirmationAlertDialog, Flex, IconButton, Text, useDisclosure } from '@invoke-ai/ui-library';
|
||||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||||
|
import { $isMenuOpen } from 'features/stylePresets/store/isMenuOpen';
|
||||||
import {
|
import {
|
||||||
isModalOpenChanged,
|
isModalOpenChanged,
|
||||||
prefilledFormDataChanged,
|
prefilledFormDataChanged,
|
||||||
updatingStylePresetIdChanged,
|
updatingStylePresetIdChanged,
|
||||||
} from 'features/stylePresets/store/stylePresetModalSlice';
|
} from 'features/stylePresets/store/stylePresetModalSlice';
|
||||||
import { activeStylePresetIdChanged, isMenuOpenChanged } from 'features/stylePresets/store/stylePresetSlice';
|
import { activeStylePresetIdChanged } from 'features/stylePresets/store/stylePresetSlice';
|
||||||
import { toast } from 'features/toast/toast';
|
import { toast } from 'features/toast/toast';
|
||||||
import type { MouseEvent } from 'react';
|
import type { MouseEvent } from 'react';
|
||||||
import { useCallback } from 'react';
|
import { useCallback } from 'react';
|
||||||
@ -46,7 +47,7 @@ export const StylePresetListItem = ({ preset }: { preset: StylePresetRecordWithI
|
|||||||
|
|
||||||
const handleClickApply = useCallback(async () => {
|
const handleClickApply = useCallback(async () => {
|
||||||
dispatch(activeStylePresetIdChanged(preset.id));
|
dispatch(activeStylePresetIdChanged(preset.id));
|
||||||
dispatch(isMenuOpenChanged(false));
|
$isMenuOpen.set(false);
|
||||||
}, [dispatch, preset.id]);
|
}, [dispatch, preset.id]);
|
||||||
|
|
||||||
const handleClickDelete = useCallback(
|
const handleClickDelete = useCallback(
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { Flex, IconButton } from '@invoke-ai/ui-library';
|
import { Flex, IconButton } from '@invoke-ai/ui-library';
|
||||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
import { useStore } from '@nanostores/react';
|
||||||
import { isMenuOpenChanged } from 'features/stylePresets/store/stylePresetSlice';
|
import { $isMenuOpen } from 'features/stylePresets/store/isMenuOpen';
|
||||||
import { useCallback } from 'react';
|
import { useCallback } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { PiCaretDownBold } from 'react-icons/pi';
|
import { PiCaretDownBold } from 'react-icons/pi';
|
||||||
@ -8,13 +8,12 @@ import { PiCaretDownBold } from 'react-icons/pi';
|
|||||||
import { ActiveStylePreset } from './ActiveStylePreset';
|
import { ActiveStylePreset } from './ActiveStylePreset';
|
||||||
|
|
||||||
export const StylePresetMenuTrigger = () => {
|
export const StylePresetMenuTrigger = () => {
|
||||||
const isMenuOpen = useAppSelector((s) => s.stylePreset.isMenuOpen);
|
const isMenuOpen = useStore($isMenuOpen);
|
||||||
const dispatch = useAppDispatch();
|
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
const handleToggle = useCallback(() => {
|
const handleToggle = useCallback(() => {
|
||||||
dispatch(isMenuOpenChanged(!isMenuOpen));
|
$isMenuOpen.set(!isMenuOpen);
|
||||||
}, [dispatch, isMenuOpen]);
|
}, [isMenuOpen]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Flex
|
<Flex
|
||||||
|
@ -5,7 +5,7 @@ export const PRESET_PLACEHOLDER = `[prompt]`;
|
|||||||
|
|
||||||
export const buildPresetModifiedPrompt = (presetPrompt: string, currentPrompt: string) => {
|
export const buildPresetModifiedPrompt = (presetPrompt: string, currentPrompt: string) => {
|
||||||
return presetPrompt.includes(PRESET_PLACEHOLDER)
|
return presetPrompt.includes(PRESET_PLACEHOLDER)
|
||||||
? presetPrompt.replace(new RegExp(PRESET_PLACEHOLDER), currentPrompt)
|
? presetPrompt.replace(PRESET_PLACEHOLDER, currentPrompt)
|
||||||
: `${currentPrompt} ${presetPrompt}`;
|
: `${currentPrompt} ${presetPrompt}`;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -0,0 +1,6 @@
|
|||||||
|
import { atom } from 'nanostores';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tracks whether or not the style preset menu is open.
|
||||||
|
*/
|
||||||
|
export const $isMenuOpen = atom<boolean>(false);
|
@ -5,7 +5,6 @@ import type { PersistConfig } from 'app/store/store';
|
|||||||
import type { StylePresetState } from './types';
|
import type { StylePresetState } from './types';
|
||||||
|
|
||||||
const initialState: StylePresetState = {
|
const initialState: StylePresetState = {
|
||||||
isMenuOpen: false,
|
|
||||||
activeStylePresetId: null,
|
activeStylePresetId: null,
|
||||||
searchTerm: '',
|
searchTerm: '',
|
||||||
viewMode: false,
|
viewMode: false,
|
||||||
@ -15,9 +14,6 @@ export const stylePresetSlice = createSlice({
|
|||||||
name: 'stylePreset',
|
name: 'stylePreset',
|
||||||
initialState: initialState,
|
initialState: initialState,
|
||||||
reducers: {
|
reducers: {
|
||||||
isMenuOpenChanged: (state, action: PayloadAction<boolean>) => {
|
|
||||||
state.isMenuOpen = action.payload;
|
|
||||||
},
|
|
||||||
activeStylePresetIdChanged: (state, action: PayloadAction<string | null>) => {
|
activeStylePresetIdChanged: (state, action: PayloadAction<string | null>) => {
|
||||||
state.activeStylePresetId = action.payload;
|
state.activeStylePresetId = action.payload;
|
||||||
},
|
},
|
||||||
@ -30,8 +26,7 @@ export const stylePresetSlice = createSlice({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export const { isMenuOpenChanged, activeStylePresetIdChanged, searchTermChanged, viewModeChanged } =
|
export const { activeStylePresetIdChanged, searchTermChanged, viewModeChanged } = stylePresetSlice.actions;
|
||||||
stylePresetSlice.actions;
|
|
||||||
|
|
||||||
/* eslint-disable-next-line @typescript-eslint/no-explicit-any */
|
/* eslint-disable-next-line @typescript-eslint/no-explicit-any */
|
||||||
const migrateStylePresetState = (state: any): any => {
|
const migrateStylePresetState = (state: any): any => {
|
||||||
|
@ -12,7 +12,6 @@ export type PrefilledFormData = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export type StylePresetState = {
|
export type StylePresetState = {
|
||||||
isMenuOpen: boolean;
|
|
||||||
activeStylePresetId: string | null;
|
activeStylePresetId: string | null;
|
||||||
searchTerm: string;
|
searchTerm: string;
|
||||||
viewMode: boolean;
|
viewMode: boolean;
|
||||||
|
@ -3,7 +3,8 @@ export const getViewModeChunks = (currentPrompt: string, presetPrompt?: string):
|
|||||||
if (!presetPrompt || !presetPrompt.length) {
|
if (!presetPrompt || !presetPrompt.length) {
|
||||||
return ['', currentPrompt, ''];
|
return ['', currentPrompt, ''];
|
||||||
}
|
}
|
||||||
const chunks = presetPrompt.split(PRESET_PLACEHOLDER);
|
const [firstPart, ...remainingParts] = presetPrompt.split(PRESET_PLACEHOLDER);
|
||||||
|
const chunks = [firstPart, remainingParts.join(PRESET_PLACEHOLDER)];
|
||||||
if (chunks.length === 1) {
|
if (chunks.length === 1) {
|
||||||
return ['', currentPrompt, chunks[0] ?? ''];
|
return ['', currentPrompt, chunks[0] ?? ''];
|
||||||
} else {
|
} else {
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import { Box, Flex } from '@invoke-ai/ui-library';
|
import { Box, Flex } from '@invoke-ai/ui-library';
|
||||||
|
import { useStore } from '@nanostores/react';
|
||||||
import { useAppSelector } from 'app/store/storeHooks';
|
import { useAppSelector } from 'app/store/storeHooks';
|
||||||
import { overlayScrollbarsParams } from 'common/components/OverlayScrollbars/constants';
|
import { overlayScrollbarsParams } from 'common/components/OverlayScrollbars/constants';
|
||||||
import { Prompts } from 'features/parameters/components/Prompts/Prompts';
|
import { Prompts } from 'features/parameters/components/Prompts/Prompts';
|
||||||
@ -11,6 +12,7 @@ import { ImageSettingsAccordion } from 'features/settingsAccordions/components/I
|
|||||||
import { RefinerSettingsAccordion } from 'features/settingsAccordions/components/RefinerSettingsAccordion/RefinerSettingsAccordion';
|
import { RefinerSettingsAccordion } from 'features/settingsAccordions/components/RefinerSettingsAccordion/RefinerSettingsAccordion';
|
||||||
import { StylePresetMenu } from 'features/stylePresets/components/StylePresetMenu';
|
import { StylePresetMenu } from 'features/stylePresets/components/StylePresetMenu';
|
||||||
import { StylePresetMenuTrigger } from 'features/stylePresets/components/StylePresetMenuTrigger';
|
import { StylePresetMenuTrigger } from 'features/stylePresets/components/StylePresetMenuTrigger';
|
||||||
|
import { $isMenuOpen } from 'features/stylePresets/store/isMenuOpen';
|
||||||
import { OverlayScrollbarsComponent } from 'overlayscrollbars-react';
|
import { OverlayScrollbarsComponent } from 'overlayscrollbars-react';
|
||||||
import type { CSSProperties } from 'react';
|
import type { CSSProperties } from 'react';
|
||||||
import { memo } from 'react';
|
import { memo } from 'react';
|
||||||
@ -22,7 +24,7 @@ const overlayScrollbarsStyles: CSSProperties = {
|
|||||||
|
|
||||||
const ParametersPanelCanvas = () => {
|
const ParametersPanelCanvas = () => {
|
||||||
const isSDXL = useAppSelector((s) => s.generation.model?.base === 'sdxl');
|
const isSDXL = useAppSelector((s) => s.generation.model?.base === 'sdxl');
|
||||||
const isMenuOpen = useAppSelector((s) => s.stylePreset.isMenuOpen);
|
const isMenuOpen = useStore($isMenuOpen);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Flex w="full" h="full" flexDir="column" gap={2}>
|
<Flex w="full" h="full" flexDir="column" gap={2}>
|
||||||
@ -30,13 +32,13 @@ const ParametersPanelCanvas = () => {
|
|||||||
<StylePresetMenuTrigger />
|
<StylePresetMenuTrigger />
|
||||||
<Flex w="full" h="full" position="relative">
|
<Flex w="full" h="full" position="relative">
|
||||||
<Box position="absolute" top={0} left={0} right={0} bottom={0}>
|
<Box position="absolute" top={0} left={0} right={0} bottom={0}>
|
||||||
{isMenuOpen ? (
|
{isMenuOpen && (
|
||||||
<OverlayScrollbarsComponent defer style={overlayScrollbarsStyles} options={overlayScrollbarsParams.options}>
|
<OverlayScrollbarsComponent defer style={overlayScrollbarsStyles} options={overlayScrollbarsParams.options}>
|
||||||
<Flex gap={2} flexDirection="column" h="full" w="full">
|
<Flex gap={2} flexDirection="column" h="full" w="full">
|
||||||
<StylePresetMenu />
|
<StylePresetMenu />
|
||||||
</Flex>
|
</Flex>
|
||||||
</OverlayScrollbarsComponent>
|
</OverlayScrollbarsComponent>
|
||||||
) : (
|
)}
|
||||||
<OverlayScrollbarsComponent defer style={overlayScrollbarsStyles} options={overlayScrollbarsParams.options}>
|
<OverlayScrollbarsComponent defer style={overlayScrollbarsStyles} options={overlayScrollbarsParams.options}>
|
||||||
<Flex gap={2} flexDirection="column" h="full" w="full">
|
<Flex gap={2} flexDirection="column" h="full" w="full">
|
||||||
<Prompts />
|
<Prompts />
|
||||||
@ -48,7 +50,6 @@ const ParametersPanelCanvas = () => {
|
|||||||
<AdvancedSettingsAccordion />
|
<AdvancedSettingsAccordion />
|
||||||
</Flex>
|
</Flex>
|
||||||
</OverlayScrollbarsComponent>
|
</OverlayScrollbarsComponent>
|
||||||
)}
|
|
||||||
</Box>
|
</Box>
|
||||||
</Flex>
|
</Flex>
|
||||||
</Flex>
|
</Flex>
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import type { ChakraProps } from '@invoke-ai/ui-library';
|
import type { ChakraProps } from '@invoke-ai/ui-library';
|
||||||
import { Box, Flex, Tab, TabList, TabPanel, TabPanels, Tabs } from '@invoke-ai/ui-library';
|
import { Box, Flex, Tab, TabList, TabPanel, TabPanels, Tabs } from '@invoke-ai/ui-library';
|
||||||
|
import { useStore } from '@nanostores/react';
|
||||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||||
import { overlayScrollbarsParams } from 'common/components/OverlayScrollbars/constants';
|
import { overlayScrollbarsParams } from 'common/components/OverlayScrollbars/constants';
|
||||||
import { ControlLayersPanelContent } from 'features/controlLayers/components/ControlLayersPanelContent';
|
import { ControlLayersPanelContent } from 'features/controlLayers/components/ControlLayersPanelContent';
|
||||||
@ -15,6 +16,7 @@ import { ImageSettingsAccordion } from 'features/settingsAccordions/components/I
|
|||||||
import { RefinerSettingsAccordion } from 'features/settingsAccordions/components/RefinerSettingsAccordion/RefinerSettingsAccordion';
|
import { RefinerSettingsAccordion } from 'features/settingsAccordions/components/RefinerSettingsAccordion/RefinerSettingsAccordion';
|
||||||
import { StylePresetMenu } from 'features/stylePresets/components/StylePresetMenu';
|
import { StylePresetMenu } from 'features/stylePresets/components/StylePresetMenu';
|
||||||
import { StylePresetMenuTrigger } from 'features/stylePresets/components/StylePresetMenuTrigger';
|
import { StylePresetMenuTrigger } from 'features/stylePresets/components/StylePresetMenuTrigger';
|
||||||
|
import { $isMenuOpen } from 'features/stylePresets/store/isMenuOpen';
|
||||||
import { activeTabNameSelector } from 'features/ui/store/uiSelectors';
|
import { activeTabNameSelector } from 'features/ui/store/uiSelectors';
|
||||||
import { OverlayScrollbarsComponent } from 'overlayscrollbars-react';
|
import { OverlayScrollbarsComponent } from 'overlayscrollbars-react';
|
||||||
import type { CSSProperties } from 'react';
|
import type { CSSProperties } from 'react';
|
||||||
@ -61,7 +63,7 @@ const ParametersPanelTextToImage = () => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
const ref = useRef<HTMLDivElement>(null);
|
const ref = useRef<HTMLDivElement>(null);
|
||||||
const isMenuOpen = useAppSelector((s) => s.stylePreset.isMenuOpen);
|
const isMenuOpen = useStore($isMenuOpen);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Flex w="full" h="full" flexDir="column" gap={2}>
|
<Flex w="full" h="full" flexDir="column" gap={2}>
|
||||||
@ -69,13 +71,13 @@ const ParametersPanelTextToImage = () => {
|
|||||||
<StylePresetMenuTrigger />
|
<StylePresetMenuTrigger />
|
||||||
<Flex w="full" h="full" position="relative">
|
<Flex w="full" h="full" position="relative">
|
||||||
<Box position="absolute" top={0} left={0} right={0} bottom={0} ref={ref}>
|
<Box position="absolute" top={0} left={0} right={0} bottom={0} ref={ref}>
|
||||||
{isMenuOpen ? (
|
{isMenuOpen && (
|
||||||
<OverlayScrollbarsComponent defer style={overlayScrollbarsStyles} options={overlayScrollbarsParams.options}>
|
<OverlayScrollbarsComponent defer style={overlayScrollbarsStyles} options={overlayScrollbarsParams.options}>
|
||||||
<Flex gap={2} flexDirection="column" h="full" w="full">
|
<Flex gap={2} flexDirection="column" h="full" w="full">
|
||||||
<StylePresetMenu />
|
<StylePresetMenu />
|
||||||
</Flex>
|
</Flex>
|
||||||
</OverlayScrollbarsComponent>
|
</OverlayScrollbarsComponent>
|
||||||
) : (
|
)}
|
||||||
<OverlayScrollbarsComponent defer style={overlayScrollbarsStyles} options={overlayScrollbarsParams.options}>
|
<OverlayScrollbarsComponent defer style={overlayScrollbarsStyles} options={overlayScrollbarsParams.options}>
|
||||||
<Flex gap={2} flexDirection="column" h="full" w="full">
|
<Flex gap={2} flexDirection="column" h="full" w="full">
|
||||||
<Prompts />
|
<Prompts />
|
||||||
@ -119,7 +121,6 @@ const ParametersPanelTextToImage = () => {
|
|||||||
</Tabs>
|
</Tabs>
|
||||||
</Flex>
|
</Flex>
|
||||||
</OverlayScrollbarsComponent>
|
</OverlayScrollbarsComponent>
|
||||||
)}
|
|
||||||
</Box>
|
</Box>
|
||||||
</Flex>
|
</Flex>
|
||||||
</Flex>
|
</Flex>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { Box, Flex } from '@invoke-ai/ui-library';
|
import { Box, Flex } from '@invoke-ai/ui-library';
|
||||||
import { useAppSelector } from 'app/store/storeHooks';
|
import { useStore } from '@nanostores/react';
|
||||||
import { overlayScrollbarsParams } from 'common/components/OverlayScrollbars/constants';
|
import { overlayScrollbarsParams } from 'common/components/OverlayScrollbars/constants';
|
||||||
import { Prompts } from 'features/parameters/components/Prompts/Prompts';
|
import { Prompts } from 'features/parameters/components/Prompts/Prompts';
|
||||||
import QueueControls from 'features/queue/components/QueueControls';
|
import QueueControls from 'features/queue/components/QueueControls';
|
||||||
@ -8,6 +8,7 @@ import { GenerationSettingsAccordion } from 'features/settingsAccordions/compone
|
|||||||
import { UpscaleSettingsAccordion } from 'features/settingsAccordions/components/UpscaleSettingsAccordion/UpscaleSettingsAccordion';
|
import { UpscaleSettingsAccordion } from 'features/settingsAccordions/components/UpscaleSettingsAccordion/UpscaleSettingsAccordion';
|
||||||
import { StylePresetMenu } from 'features/stylePresets/components/StylePresetMenu';
|
import { StylePresetMenu } from 'features/stylePresets/components/StylePresetMenu';
|
||||||
import { StylePresetMenuTrigger } from 'features/stylePresets/components/StylePresetMenuTrigger';
|
import { StylePresetMenuTrigger } from 'features/stylePresets/components/StylePresetMenuTrigger';
|
||||||
|
import { $isMenuOpen } from 'features/stylePresets/store/isMenuOpen';
|
||||||
import { OverlayScrollbarsComponent } from 'overlayscrollbars-react';
|
import { OverlayScrollbarsComponent } from 'overlayscrollbars-react';
|
||||||
import type { CSSProperties } from 'react';
|
import type { CSSProperties } from 'react';
|
||||||
import { memo } from 'react';
|
import { memo } from 'react';
|
||||||
@ -18,20 +19,20 @@ const overlayScrollbarsStyles: CSSProperties = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const ParametersPanelUpscale = () => {
|
const ParametersPanelUpscale = () => {
|
||||||
const isMenuOpen = useAppSelector((s) => s.stylePreset.isMenuOpen);
|
const isMenuOpen = useStore($isMenuOpen);
|
||||||
return (
|
return (
|
||||||
<Flex w="full" h="full" flexDir="column" gap={2}>
|
<Flex w="full" h="full" flexDir="column" gap={2}>
|
||||||
<QueueControls />
|
<QueueControls />
|
||||||
<StylePresetMenuTrigger />
|
<StylePresetMenuTrigger />
|
||||||
<Flex w="full" h="full" position="relative">
|
<Flex w="full" h="full" position="relative">
|
||||||
<Box position="absolute" top={0} left={0} right={0} bottom={0}>
|
<Box position="absolute" top={0} left={0} right={0} bottom={0}>
|
||||||
{isMenuOpen ? (
|
{isMenuOpen && (
|
||||||
<OverlayScrollbarsComponent defer style={overlayScrollbarsStyles} options={overlayScrollbarsParams.options}>
|
<OverlayScrollbarsComponent defer style={overlayScrollbarsStyles} options={overlayScrollbarsParams.options}>
|
||||||
<Flex gap={2} flexDirection="column" h="full" w="full">
|
<Flex gap={2} flexDirection="column" h="full" w="full">
|
||||||
<StylePresetMenu />
|
<StylePresetMenu />
|
||||||
</Flex>
|
</Flex>
|
||||||
</OverlayScrollbarsComponent>
|
</OverlayScrollbarsComponent>
|
||||||
) : (
|
)}
|
||||||
<OverlayScrollbarsComponent defer style={overlayScrollbarsStyles} options={overlayScrollbarsParams.options}>
|
<OverlayScrollbarsComponent defer style={overlayScrollbarsStyles} options={overlayScrollbarsParams.options}>
|
||||||
<Flex gap={2} flexDirection="column" h="full" w="full">
|
<Flex gap={2} flexDirection="column" h="full" w="full">
|
||||||
<Prompts />
|
<Prompts />
|
||||||
@ -40,7 +41,6 @@ const ParametersPanelUpscale = () => {
|
|||||||
<AdvancedSettingsAccordion />
|
<AdvancedSettingsAccordion />
|
||||||
</Flex>
|
</Flex>
|
||||||
</OverlayScrollbarsComponent>
|
</OverlayScrollbarsComponent>
|
||||||
)}
|
|
||||||
</Box>
|
</Box>
|
||||||
</Flex>
|
</Flex>
|
||||||
</Flex>
|
</Flex>
|
||||||
|
@ -44,9 +44,8 @@ export const stylePresetsApi = api.injectEndpoints({
|
|||||||
if (image) {
|
if (image) {
|
||||||
formData.append('image', image);
|
formData.append('image', image);
|
||||||
}
|
}
|
||||||
formData.append('name', name);
|
|
||||||
formData.append('positive_prompt', positive_prompt);
|
formData.append('data', JSON.stringify({ name, positive_prompt, negative_prompt }));
|
||||||
formData.append('negative_prompt', negative_prompt);
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
url: buildStylePresetsUrl(),
|
url: buildStylePresetsUrl(),
|
||||||
@ -70,10 +69,7 @@ export const stylePresetsApi = api.injectEndpoints({
|
|||||||
if (image) {
|
if (image) {
|
||||||
formData.append('image', image);
|
formData.append('image', image);
|
||||||
}
|
}
|
||||||
|
formData.append('data', JSON.stringify({ name, positive_prompt, negative_prompt }));
|
||||||
formData.append('name', name);
|
|
||||||
formData.append('positive_prompt', positive_prompt);
|
|
||||||
formData.append('negative_prompt', negative_prompt);
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
url: buildStylePresetsUrl(`i/${id}`),
|
url: buildStylePresetsUrl(`i/${id}`),
|
||||||
|
Loading…
Reference in New Issue
Block a user