fix(ui): add missing translations (#5096)

* first string only to test

* more strings changed

* almost half strings added in json file

* more strings added

* more changes

* few strings and t function changed

* resolved

* errors resolved

* chore(ui): fmt en.json

---------

Co-authored-by: psychedelicious <4822129+psychedelicious@users.noreply.github.com>
This commit is contained in:
Rohinish 2023-11-20 11:54:03 +05:30 committed by GitHub
parent d581a3289b
commit 4d8b8a2db8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
25 changed files with 180 additions and 94 deletions

View File

@ -6,6 +6,7 @@
"flipVertically": "Flip Vertically", "flipVertically": "Flip Vertically",
"invokeProgressBar": "Invoke progress bar", "invokeProgressBar": "Invoke progress bar",
"menu": "Menu", "menu": "Menu",
"mode": "Mode",
"modelSelect": "Model Select", "modelSelect": "Model Select",
"modifyConfig": "Modify Config", "modifyConfig": "Modify Config",
"nextImage": "Next Image", "nextImage": "Next Image",
@ -30,6 +31,10 @@
"cancel": "Cancel", "cancel": "Cancel",
"changeBoard": "Change Board", "changeBoard": "Change Board",
"clearSearch": "Clear Search", "clearSearch": "Clear Search",
"deleteBoard": "Delete Board",
"deleteBoardAndImages": "Delete Board and Images",
"deleteBoardOnly": "Delete Board Only",
"deletedBoardsCannotbeRestored": "Deleted boards cannot be restored",
"loading": "Loading...", "loading": "Loading...",
"menuItemAutoAdd": "Auto-add to this Board", "menuItemAutoAdd": "Auto-add to this Board",
"move": "Move", "move": "Move",
@ -51,9 +56,12 @@
"cancel": "Cancel", "cancel": "Cancel",
"close": "Close", "close": "Close",
"on": "On", "on": "On",
"checkpoint": "Checkpoint",
"communityLabel": "Community", "communityLabel": "Community",
"controlNet": "ControlNet", "controlNet": "ControlNet",
"controlAdapter": "Control Adapter", "controlAdapter": "Control Adapter",
"data": "Data",
"details": "Details",
"ipAdapter": "IP Adapter", "ipAdapter": "IP Adapter",
"t2iAdapter": "T2I Adapter", "t2iAdapter": "T2I Adapter",
"darkMode": "Dark Mode", "darkMode": "Dark Mode",
@ -65,6 +73,7 @@
"imagePrompt": "Image Prompt", "imagePrompt": "Image Prompt",
"imageFailedToLoad": "Unable to Load Image", "imageFailedToLoad": "Unable to Load Image",
"img2img": "Image To Image", "img2img": "Image To Image",
"inpaint": "inpaint",
"langArabic": "العربية", "langArabic": "العربية",
"langBrPortuguese": "Português do Brasil", "langBrPortuguese": "Português do Brasil",
"langDutch": "Nederlands", "langDutch": "Nederlands",
@ -93,6 +102,8 @@
"nodes": "Workflow Editor", "nodes": "Workflow Editor",
"nodesDesc": "A node based system for the generation of images is under development currently. Stay tuned for updates about this amazing feature.", "nodesDesc": "A node based system for the generation of images is under development currently. Stay tuned for updates about this amazing feature.",
"openInNewTab": "Open in New Tab", "openInNewTab": "Open in New Tab",
"outpaint": "outpaint",
"outputs": "Outputs",
"postProcessDesc1": "Invoke AI offers a wide variety of post processing features. Image Upscaling and Face Restoration are already available in the WebUI. You can access them from the Advanced Options menu of the Text To Image and Image To Image tabs. You can also process images directly, using the image action buttons above the current image display or in the viewer.", "postProcessDesc1": "Invoke AI offers a wide variety of post processing features. Image Upscaling and Face Restoration are already available in the WebUI. You can access them from the Advanced Options menu of the Text To Image and Image To Image tabs. You can also process images directly, using the image action buttons above the current image display or in the viewer.",
"postProcessDesc2": "A dedicated UI will be released soon to facilitate more advanced post processing workflows.", "postProcessDesc2": "A dedicated UI will be released soon to facilitate more advanced post processing workflows.",
"postProcessDesc3": "The Invoke AI Command Line Interface offers various other features including Embiggen.", "postProcessDesc3": "The Invoke AI Command Line Interface offers various other features including Embiggen.",
@ -100,7 +111,9 @@
"postProcessing": "Post Processing", "postProcessing": "Post Processing",
"random": "Random", "random": "Random",
"reportBugLabel": "Report Bug", "reportBugLabel": "Report Bug",
"safetensors": "Safetensors",
"settingsLabel": "Settings", "settingsLabel": "Settings",
"simple": "Simple",
"statusConnected": "Connected", "statusConnected": "Connected",
"statusConvertingModel": "Converting Model", "statusConvertingModel": "Converting Model",
"statusDisconnected": "Disconnected", "statusDisconnected": "Disconnected",
@ -127,6 +140,7 @@
"statusSavingImage": "Saving Image", "statusSavingImage": "Saving Image",
"statusUpscaling": "Upscaling", "statusUpscaling": "Upscaling",
"statusUpscalingESRGAN": "Upscaling (ESRGAN)", "statusUpscalingESRGAN": "Upscaling (ESRGAN)",
"template": "Template",
"training": "Training", "training": "Training",
"trainingDesc1": "A dedicated workflow for training your own embeddings and checkpoints using Textual Inversion and Dreambooth from the web interface.", "trainingDesc1": "A dedicated workflow for training your own embeddings and checkpoints using Textual Inversion and Dreambooth from the web interface.",
"trainingDesc2": "InvokeAI already supports training custom embeddourings using Textual Inversion using the main script.", "trainingDesc2": "InvokeAI already supports training custom embeddourings using Textual Inversion using the main script.",
@ -214,6 +228,7 @@
"setControlImageDimensions": "Set Control Image Dimensions To W/H", "setControlImageDimensions": "Set Control Image Dimensions To W/H",
"showAdvanced": "Show Advanced", "showAdvanced": "Show Advanced",
"toggleControlNet": "Toggle this ControlNet", "toggleControlNet": "Toggle this ControlNet",
"unstarImage": "Unstar Image",
"w": "W", "w": "W",
"weight": "Weight", "weight": "Weight",
"enableIPAdapter": "Enable IP Adapter", "enableIPAdapter": "Enable IP Adapter",
@ -279,6 +294,7 @@
"next": "Next", "next": "Next",
"status": "Status", "status": "Status",
"total": "Total", "total": "Total",
"time": "Time",
"pending": "Pending", "pending": "Pending",
"in_progress": "In Progress", "in_progress": "In Progress",
"completed": "Completed", "completed": "Completed",
@ -286,6 +302,7 @@
"canceled": "Canceled", "canceled": "Canceled",
"completedIn": "Completed in", "completedIn": "Completed in",
"batch": "Batch", "batch": "Batch",
"batchFieldValues": "Batch Field Values",
"item": "Item", "item": "Item",
"session": "Session", "session": "Session",
"batchValues": "Batch Values", "batchValues": "Batch Values",
@ -335,6 +352,7 @@
"loading": "Loading", "loading": "Loading",
"loadMore": "Load More", "loadMore": "Load More",
"maintainAspectRatio": "Maintain Aspect Ratio", "maintainAspectRatio": "Maintain Aspect Ratio",
"noImageSelected": "No Image Selected",
"noImagesInGallery": "No Images to Display", "noImagesInGallery": "No Images to Display",
"setCurrentImage": "Set as Current Image", "setCurrentImage": "Set as Current Image",
"showGenerations": "Show Generations", "showGenerations": "Show Generations",
@ -606,6 +624,7 @@
"cannotUseSpaces": "Cannot Use Spaces", "cannotUseSpaces": "Cannot Use Spaces",
"checkpointFolder": "Checkpoint Folder", "checkpointFolder": "Checkpoint Folder",
"checkpointModels": "Checkpoints", "checkpointModels": "Checkpoints",
"checkpointOrSafetensors": "$t(common.checkpoint) / $t(common.safetensors)",
"clearCheckpointFolder": "Clear Checkpoint Folder", "clearCheckpointFolder": "Clear Checkpoint Folder",
"closeAdvanced": "Close Advanced", "closeAdvanced": "Close Advanced",
"config": "Config", "config": "Config",
@ -685,6 +704,7 @@
"nameValidationMsg": "Enter a name for your model", "nameValidationMsg": "Enter a name for your model",
"noCustomLocationProvided": "No Custom Location Provided", "noCustomLocationProvided": "No Custom Location Provided",
"noModels": "No Models Found", "noModels": "No Models Found",
"noModelSelected": "No Model Selected",
"noModelsFound": "No Models Found", "noModelsFound": "No Models Found",
"none": "none", "none": "none",
"notLoaded": "not loaded", "notLoaded": "not loaded",
@ -730,6 +750,8 @@
"widthValidationMsg": "Default width of your model." "widthValidationMsg": "Default width of your model."
}, },
"models": { "models": {
"addLora": "Add LoRA",
"esrganModel": "ESRGAN Model",
"loading": "loading", "loading": "loading",
"noLoRAsAvailable": "No LoRAs available", "noLoRAsAvailable": "No LoRAs available",
"noMatchingLoRAs": "No matching LoRAs", "noMatchingLoRAs": "No matching LoRAs",
@ -1010,6 +1032,7 @@
"maskAdjustmentsHeader": "Mask Adjustments", "maskAdjustmentsHeader": "Mask Adjustments",
"maskBlur": "Blur", "maskBlur": "Blur",
"maskBlurMethod": "Blur Method", "maskBlurMethod": "Blur Method",
"maskEdge": "Mask Edge",
"negativePromptPlaceholder": "Negative Prompt", "negativePromptPlaceholder": "Negative Prompt",
"noiseSettings": "Noise", "noiseSettings": "Noise",
"noiseThreshold": "Noise Threshold", "noiseThreshold": "Noise Threshold",
@ -1057,6 +1080,7 @@
"upscale": "Upscale (Shift + U)", "upscale": "Upscale (Shift + U)",
"upscaleImage": "Upscale Image", "upscaleImage": "Upscale Image",
"upscaling": "Upscaling", "upscaling": "Upscaling",
"unmasked": "Unmasked",
"useAll": "Use All", "useAll": "Use All",
"useCpuNoise": "Use CPU Noise", "useCpuNoise": "Use CPU Noise",
"cpuNoise": "CPU Noise", "cpuNoise": "CPU Noise",
@ -1078,6 +1102,7 @@
"dynamicPrompts": "Dynamic Prompts", "dynamicPrompts": "Dynamic Prompts",
"enableDynamicPrompts": "Enable Dynamic Prompts", "enableDynamicPrompts": "Enable Dynamic Prompts",
"maxPrompts": "Max Prompts", "maxPrompts": "Max Prompts",
"promptsPreview": "Prompts Preview",
"promptsWithCount_one": "{{count}} Prompt", "promptsWithCount_one": "{{count}} Prompt",
"promptsWithCount_other": "{{count}} Prompts", "promptsWithCount_other": "{{count}} Prompts",
"seedBehaviour": { "seedBehaviour": {
@ -1117,7 +1142,10 @@
"displayHelpIcons": "Display Help Icons", "displayHelpIcons": "Display Help Icons",
"displayInProgress": "Display Progress Images", "displayInProgress": "Display Progress Images",
"enableImageDebugging": "Enable Image Debugging", "enableImageDebugging": "Enable Image Debugging",
"enableInformationalPopovers": "Enable Informational Popovers",
"enableInvisibleWatermark": "Enable Invisible Watermark",
"enableNodesEditor": "Enable Nodes Editor", "enableNodesEditor": "Enable Nodes Editor",
"enableNSFWChecker": "Enable NSFW Checker",
"experimental": "Experimental", "experimental": "Experimental",
"favoriteSchedulers": "Favorite Schedulers", "favoriteSchedulers": "Favorite Schedulers",
"favoriteSchedulersPlaceholder": "No schedulers favorited", "favoriteSchedulersPlaceholder": "No schedulers favorited",
@ -1217,7 +1245,8 @@
"sentToImageToImage": "Sent To Image To Image", "sentToImageToImage": "Sent To Image To Image",
"sentToUnifiedCanvas": "Sent to Unified Canvas", "sentToUnifiedCanvas": "Sent to Unified Canvas",
"serverError": "Server Error", "serverError": "Server Error",
"setCanvasInitialImage": "Set as canvas initial image", "setAsCanvasInitialImage": "Set as canvas initial image",
"setCanvasInitialImage": "Set canvas initial image",
"setControlImage": "Set as control image", "setControlImage": "Set as control image",
"setIPAdapterImage": "Set as IP Adapter Image", "setIPAdapterImage": "Set as IP Adapter Image",
"setInitialImage": "Set as initial image", "setInitialImage": "Set as initial image",
@ -1275,11 +1304,15 @@
}, },
"compositingBlur": { "compositingBlur": {
"heading": "Blur", "heading": "Blur",
"paragraphs": ["The blur radius of the mask."] "paragraphs": [
"The blur radius of the mask."
]
}, },
"compositingBlurMethod": { "compositingBlurMethod": {
"heading": "Blur Method", "heading": "Blur Method",
"paragraphs": ["The method of blur applied to the masked area."] "paragraphs": [
"The method of blur applied to the masked area."
]
}, },
"compositingCoherencePass": { "compositingCoherencePass": {
"heading": "Coherence Pass", "heading": "Coherence Pass",
@ -1289,7 +1322,9 @@
}, },
"compositingCoherenceMode": { "compositingCoherenceMode": {
"heading": "Mode", "heading": "Mode",
"paragraphs": ["The mode of the Coherence Pass."] "paragraphs": [
"The mode of the Coherence Pass."
]
}, },
"compositingCoherenceSteps": { "compositingCoherenceSteps": {
"heading": "Steps", "heading": "Steps",
@ -1307,7 +1342,9 @@
}, },
"compositingMaskAdjustments": { "compositingMaskAdjustments": {
"heading": "Mask Adjustments", "heading": "Mask Adjustments",
"paragraphs": ["Adjust the mask."] "paragraphs": [
"Adjust the mask."
]
}, },
"controlNetBeginEnd": { "controlNetBeginEnd": {
"heading": "Begin / End Step Percentage", "heading": "Begin / End Step Percentage",
@ -1365,7 +1402,9 @@
}, },
"infillMethod": { "infillMethod": {
"heading": "Infill Method", "heading": "Infill Method",
"paragraphs": ["Method to infill the selected area."] "paragraphs": [
"Method to infill the selected area."
]
}, },
"lora": { "lora": {
"heading": "LoRA Weight", "heading": "LoRA Weight",

View File

@ -79,7 +79,7 @@ export const addImageUploadedFulfilledListener = () => {
dispatch( dispatch(
addToast({ addToast({
...DEFAULT_UPLOADED_TOAST, ...DEFAULT_UPLOADED_TOAST,
description: t('toast.setCanvasInitialImage'), description: t('toast.setAsCanvasInitialImage'),
}) })
); );
return; return;

View File

@ -17,6 +17,7 @@ import IAIInformationalPopover from 'common/components/IAIInformationalPopover/I
import ScrollableContent from 'features/nodes/components/sidePanel/ScrollableContent'; import ScrollableContent from 'features/nodes/components/sidePanel/ScrollableContent';
import { memo } from 'react'; import { memo } from 'react';
import { FaCircleExclamation } from 'react-icons/fa6'; import { FaCircleExclamation } from 'react-icons/fa6';
import { useTranslation } from 'react-i18next';
const selector = createSelector( const selector = createSelector(
stateSelector, stateSelector,
@ -38,6 +39,7 @@ const listItemStyles: ChakraProps['sx'] = {
}; };
const ParamDynamicPromptsPreview = () => { const ParamDynamicPromptsPreview = () => {
const { t } = useTranslation();
const { prompts, parsingError, isLoading, isError } = const { prompts, parsingError, isLoading, isError } =
useAppSelector(selector); useAppSelector(selector);
@ -69,7 +71,7 @@ const ParamDynamicPromptsPreview = () => {
overflow="hidden" overflow="hidden"
textOverflow="ellipsis" textOverflow="ellipsis"
> >
Prompts Preview ({prompts.length}) {t('dynamicPrompts.promptsPreview')} ({prompts.length})
{parsingError && ` - ${parsingError}`} {parsingError && ` - ${parsingError}`}
</FormLabel> </FormLabel>
<Flex <Flex

View File

@ -115,7 +115,7 @@ const DeleteBoardModal = (props: Props) => {
<AlertDialogOverlay> <AlertDialogOverlay>
<AlertDialogContent> <AlertDialogContent>
<AlertDialogHeader fontSize="lg" fontWeight="bold"> <AlertDialogHeader fontSize="lg" fontWeight="bold">
Delete {boardToDelete.board_name} {t('controlnet.delete')} {boardToDelete.board_name}
</AlertDialogHeader> </AlertDialogHeader>
<AlertDialogBody> <AlertDialogBody>
@ -136,7 +136,7 @@ const DeleteBoardModal = (props: Props) => {
bottomMessage={t('boards.bottomMessage')} bottomMessage={t('boards.bottomMessage')}
/> />
)} )}
<Text>Deleted boards cannot be restored.</Text> <Text>{t('boards.deletedBoardsCannotbeRestored')}</Text>
<Text> <Text>
{canRestoreDeletedImagesFromBin {canRestoreDeletedImagesFromBin
? t('gallery.deleteImageBin') ? t('gallery.deleteImageBin')
@ -149,21 +149,21 @@ const DeleteBoardModal = (props: Props) => {
sx={{ justifyContent: 'space-between', width: 'full', gap: 2 }} sx={{ justifyContent: 'space-between', width: 'full', gap: 2 }}
> >
<IAIButton ref={cancelRef} onClick={handleClose}> <IAIButton ref={cancelRef} onClick={handleClose}>
Cancel {t('boards.cancel')}
</IAIButton> </IAIButton>
<IAIButton <IAIButton
colorScheme="warning" colorScheme="warning"
isLoading={isLoading} isLoading={isLoading}
onClick={handleDeleteBoardOnly} onClick={handleDeleteBoardOnly}
> >
Delete Board Only {t('boards.deleteBoardOnly')}
</IAIButton> </IAIButton>
<IAIButton <IAIButton
colorScheme="error" colorScheme="error"
isLoading={isLoading} isLoading={isLoading}
onClick={handleDeleteBoardAndImages} onClick={handleDeleteBoardAndImages}
> >
Delete Board and Images {t('boards.deleteBoardAndImages')}
</IAIButton> </IAIButton>
</Flex> </Flex>
</AlertDialogFooter> </AlertDialogFooter>

View File

@ -2,13 +2,14 @@ import { MenuItem } from '@chakra-ui/react';
import { memo, useCallback } from 'react'; import { memo, useCallback } from 'react';
import { FaTrash } from 'react-icons/fa'; import { FaTrash } from 'react-icons/fa';
import { BoardDTO } from 'services/api/types'; import { BoardDTO } from 'services/api/types';
import { useTranslation } from 'react-i18next';
type Props = { type Props = {
board: BoardDTO; board: BoardDTO;
setBoardToDelete?: (board?: BoardDTO) => void; setBoardToDelete?: (board?: BoardDTO) => void;
}; };
const GalleryBoardContextMenuItems = ({ board, setBoardToDelete }: Props) => { const GalleryBoardContextMenuItems = ({ board, setBoardToDelete }: Props) => {
const { t } = useTranslation();
const handleDelete = useCallback(() => { const handleDelete = useCallback(() => {
if (!setBoardToDelete) { if (!setBoardToDelete) {
return; return;
@ -34,7 +35,7 @@ const GalleryBoardContextMenuItems = ({ board, setBoardToDelete }: Props) => {
icon={<FaTrash />} icon={<FaTrash />}
onClick={handleDelete} onClick={handleDelete}
> >
Delete Board {t('boards.deleteBoard')}
</MenuItem> </MenuItem>
</> </>
); );

View File

@ -170,7 +170,10 @@ const CurrentImagePreview = () => {
useThumbailFallback useThumbailFallback
dropLabel={t('gallery.setCurrentImage')} dropLabel={t('gallery.setCurrentImage')}
noContentFallback={ noContentFallback={
<IAINoContentFallback icon={FaImage} label="No image selected" /> <IAINoContentFallback
icon={FaImage}
label={t('gallery.noImageSelected')}
/>
} }
dataTestId="image-preview" dataTestId="image-preview"
/> />

View File

@ -104,7 +104,7 @@ const MultipleSelectionMenuItems = () => {
</MenuItem> </MenuItem>
)} )}
<MenuItem icon={<FaFolder />} onClickCapture={handleChangeBoard}> <MenuItem icon={<FaFolder />} onClickCapture={handleChangeBoard}>
Change Board {t('boards.changeBoard')}
</MenuItem> </MenuItem>
<MenuItem <MenuItem
sx={{ color: 'error.600', _dark: { color: 'error.300' } }} sx={{ color: 'error.600', _dark: { color: 'error.300' } }}

View File

@ -224,14 +224,14 @@ const SingleSelectionMenuItems = (props: SingleSelectionMenuItemsProps) => {
</MenuItem> </MenuItem>
)} )}
<MenuItem icon={<FaFolder />} onClickCapture={handleChangeBoard}> <MenuItem icon={<FaFolder />} onClickCapture={handleChangeBoard}>
Change Board {t('boards.changeBoard')}
</MenuItem> </MenuItem>
{imageDTO.starred ? ( {imageDTO.starred ? (
<MenuItem <MenuItem
icon={customStarUi ? customStarUi.off.icon : <MdStar />} icon={customStarUi ? customStarUi.off.icon : <MdStar />}
onClickCapture={handleUnstarImage} onClickCapture={handleUnstarImage}
> >
{customStarUi ? customStarUi.off.text : `Unstar Image`} {customStarUi ? customStarUi.off.text : t('controlnet.unstarImage')}
</MenuItem> </MenuItem>
) : ( ) : (
<MenuItem <MenuItem

View File

@ -95,7 +95,7 @@ const ParamLoRASelect = () => {
return ( return (
<IAIMantineSearchableSelect <IAIMantineSearchableSelect
placeholder={data.length === 0 ? 'All LoRAs added' : 'Add LoRA'} placeholder={data.length === 0 ? 'All LoRAs added' : t('models.addLora')}
value={null} value={null}
data={data} data={data}
nothingFound="No matching LoRAs" nothingFound="No matching LoRAs"

View File

@ -3,8 +3,10 @@ import IAIButton from 'common/components/IAIButton';
import { useCallback, useState } from 'react'; import { useCallback, useState } from 'react';
import AdvancedAddModels from './AdvancedAddModels'; import AdvancedAddModels from './AdvancedAddModels';
import SimpleAddModels from './SimpleAddModels'; import SimpleAddModels from './SimpleAddModels';
import { useTranslation } from 'react-i18next';
export default function AddModels() { export default function AddModels() {
const { t } = useTranslation();
const [addModelMode, setAddModelMode] = useState<'simple' | 'advanced'>( const [addModelMode, setAddModelMode] = useState<'simple' | 'advanced'>(
'simple' 'simple'
); );
@ -27,14 +29,14 @@ export default function AddModels() {
isChecked={addModelMode == 'simple'} isChecked={addModelMode == 'simple'}
onClick={handleAddModelSimple} onClick={handleAddModelSimple}
> >
Simple {t('common.simple')}
</IAIButton> </IAIButton>
<IAIButton <IAIButton
size="sm" size="sm"
isChecked={addModelMode == 'advanced'} isChecked={addModelMode == 'advanced'}
onClick={handleAddModelAdvanced} onClick={handleAddModelAdvanced}
> >
Advanced {t('common.advanced')}
</IAIButton> </IAIButton>
</ButtonGroup> </ButtonGroup>
<Flex <Flex

View File

@ -1,16 +1,11 @@
import { Flex } from '@chakra-ui/react'; import { Flex } from '@chakra-ui/react';
import { SelectItem } from '@mantine/core'; import { SelectItem } from '@mantine/core';
import IAIMantineSelect from 'common/components/IAIMantineSelect'; import IAIMantineSelect from 'common/components/IAIMantineSelect';
import { useCallback, useState } from 'react'; import { useCallback, useMemo, useState } from 'react';
import AdvancedAddCheckpoint from './AdvancedAddCheckpoint'; import AdvancedAddCheckpoint from './AdvancedAddCheckpoint';
import AdvancedAddDiffusers from './AdvancedAddDiffusers'; import AdvancedAddDiffusers from './AdvancedAddDiffusers';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
export const advancedAddModeData: SelectItem[] = [
{ label: 'Diffusers', value: 'diffusers' },
{ label: 'Checkpoint / Safetensors', value: 'checkpoint' },
];
export type ManualAddMode = 'diffusers' | 'checkpoint'; export type ManualAddMode = 'diffusers' | 'checkpoint';
export default function AdvancedAddModels() { export default function AdvancedAddModels() {
@ -25,6 +20,14 @@ export default function AdvancedAddModels() {
setAdvancedAddMode(v as ManualAddMode); setAdvancedAddMode(v as ManualAddMode);
}, []); }, []);
const advancedAddModeData: SelectItem[] = useMemo(
() => [
{ label: t('modelManager.diffusersModels'), value: 'diffusers' },
{ label: t('modelManager.checkpointOrSafetensors'), value: 'checkpoint' },
],
[t]
);
return ( return (
<Flex flexDirection="column" gap={4} width="100%"> <Flex flexDirection="column" gap={4} width="100%">
<IAIMantineSelect <IAIMantineSelect

View File

@ -4,13 +4,14 @@ import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import IAIIconButton from 'common/components/IAIIconButton'; import IAIIconButton from 'common/components/IAIIconButton';
import IAIMantineSelect from 'common/components/IAIMantineSelect'; import IAIMantineSelect from 'common/components/IAIMantineSelect';
import { motion } from 'framer-motion'; import { motion } from 'framer-motion';
import { useCallback, useEffect, useState } from 'react'; import { useCallback, useEffect, useState, useMemo } from 'react';
import { FaTimes } from 'react-icons/fa'; import { FaTimes } from 'react-icons/fa';
import { setAdvancedAddScanModel } from '../../store/modelManagerSlice'; import { setAdvancedAddScanModel } from '../../store/modelManagerSlice';
import AdvancedAddCheckpoint from './AdvancedAddCheckpoint'; import AdvancedAddCheckpoint from './AdvancedAddCheckpoint';
import AdvancedAddDiffusers from './AdvancedAddDiffusers'; import AdvancedAddDiffusers from './AdvancedAddDiffusers';
import { ManualAddMode, advancedAddModeData } from './AdvancedAddModels'; import { ManualAddMode } from './AdvancedAddModels';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { SelectItem } from '@mantine/core';
export default function ScanAdvancedAddModels() { export default function ScanAdvancedAddModels() {
const advancedAddScanModel = useAppSelector( const advancedAddScanModel = useAppSelector(
@ -19,6 +20,14 @@ export default function ScanAdvancedAddModels() {
const { t } = useTranslation(); const { t } = useTranslation();
const advancedAddModeData: SelectItem[] = useMemo(
() => [
{ label: t('modelManager.diffusersModels'), value: 'diffusers' },
{ label: t('modelManager.checkpointOrSafetensors'), value: 'checkpoint' },
],
[t]
);
const [advancedAddMode, setAdvancedAddMode] = const [advancedAddMode, setAdvancedAddMode] =
useState<ManualAddMode>('diffusers'); useState<ManualAddMode>('diffusers');

View File

@ -227,7 +227,7 @@ export default function MergeModelsPanel() {
<Flex columnGap={4}> <Flex columnGap={4}>
<IAIMantineSelect <IAIMantineSelect
label="Model Type" label={t('modelManager.modelType')}
w="100%" w="100%"
data={baseModelTypeSelectData} data={baseModelTypeSelectData}
value={baseModel} value={baseModel}

View File

@ -13,6 +13,7 @@ import DiffusersModelEdit from './ModelManagerPanel/DiffusersModelEdit';
import LoRAModelEdit from './ModelManagerPanel/LoRAModelEdit'; import LoRAModelEdit from './ModelManagerPanel/LoRAModelEdit';
import ModelList from './ModelManagerPanel/ModelList'; import ModelList from './ModelManagerPanel/ModelList';
import { ALL_BASE_MODELS } from 'services/api/constants'; import { ALL_BASE_MODELS } from 'services/api/constants';
import { useTranslation } from 'react-i18next';
export default function ModelManagerPanel() { export default function ModelManagerPanel() {
const [selectedModelId, setSelectedModelId] = useState<string>(); const [selectedModelId, setSelectedModelId] = useState<string>();
@ -45,6 +46,7 @@ type ModelEditProps = {
}; };
const ModelEdit = (props: ModelEditProps) => { const ModelEdit = (props: ModelEditProps) => {
const { t } = useTranslation();
const { model } = props; const { model } = props;
if (model?.model_format === 'checkpoint') { if (model?.model_format === 'checkpoint') {
@ -75,7 +77,7 @@ const ModelEdit = (props: ModelEditProps) => {
userSelect: 'none', userSelect: 'none',
}} }}
> >
<Text variant="subtext">No Model Selected</Text> <Text variant="subtext">{t('modelManager.noModelSelected')}</Text>
</Flex> </Flex>
); );
}; };

View File

@ -54,7 +54,7 @@ export default function SyncModelsButton(props: SyncModelsButtonProps) {
minW="max-content" minW="max-content"
{...rest} {...rest}
> >
Sync Models {t('modelManager.syncModels')}
</IAIButton> </IAIButton>
) : ( ) : (
<IAIIconButton <IAIIconButton

View File

@ -127,7 +127,7 @@ const WorkflowEditorSettings = forwardRef((_, ref) => {
py: 4, py: 4,
}} }}
> >
<Heading size="sm">General</Heading> <Heading size="sm">{t('parameters.general')}</Heading>
<IAISwitch <IAISwitch
formLabelProps={formLabelProps} formLabelProps={formLabelProps}
onChange={handleChangeShouldAnimate} onChange={handleChangeShouldAnimate}
@ -159,7 +159,7 @@ const WorkflowEditorSettings = forwardRef((_, ref) => {
helperText={t('nodes.fullyContainNodesHelp')} helperText={t('nodes.fullyContainNodesHelp')}
/> />
<Heading size="sm" pt={4}> <Heading size="sm" pt={4}>
Advanced {t('common.advanced')}
</Heading> </Heading>
<IAISwitch <IAISwitch
formLabelProps={formLabelProps} formLabelProps={formLabelProps}

View File

@ -10,9 +10,11 @@ import { memo } from 'react';
import InspectorDataTab from './InspectorDataTab'; import InspectorDataTab from './InspectorDataTab';
import InspectorOutputsTab from './InspectorOutputsTab'; import InspectorOutputsTab from './InspectorOutputsTab';
import InspectorTemplateTab from './InspectorTemplateTab'; import InspectorTemplateTab from './InspectorTemplateTab';
import { useTranslation } from 'react-i18next';
import InspectorDetailsTab from './InspectorDetailsTab'; import InspectorDetailsTab from './InspectorDetailsTab';
const InspectorPanel = () => { const InspectorPanel = () => {
const { t } = useTranslation();
return ( return (
<Flex <Flex
layerStyle="first" layerStyle="first"
@ -30,10 +32,10 @@ const InspectorPanel = () => {
sx={{ display: 'flex', flexDir: 'column', w: 'full', h: 'full' }} sx={{ display: 'flex', flexDir: 'column', w: 'full', h: 'full' }}
> >
<TabList> <TabList>
<Tab>Details</Tab> <Tab>{t('common.details')}</Tab>
<Tab>Outputs</Tab> <Tab>{t('common.outputs')}</Tab>
<Tab>Data</Tab> <Tab>{t('common.data')}</Tab>
<Tab>Template</Tab> <Tab>{t('common.template')}</Tab>
</TabList> </TabList>
<TabPanels> <TabPanels>

View File

@ -10,8 +10,10 @@ import { memo } from 'react';
import WorkflowGeneralTab from './WorkflowGeneralTab'; import WorkflowGeneralTab from './WorkflowGeneralTab';
import WorkflowJSONTab from './WorkflowJSONTab'; import WorkflowJSONTab from './WorkflowJSONTab';
import WorkflowLinearTab from './WorkflowLinearTab'; import WorkflowLinearTab from './WorkflowLinearTab';
import { useTranslation } from 'react-i18next';
const WorkflowPanel = () => { const WorkflowPanel = () => {
const { t } = useTranslation();
return ( return (
<Flex <Flex
layerStyle="first" layerStyle="first"
@ -29,8 +31,8 @@ const WorkflowPanel = () => {
sx={{ display: 'flex', flexDir: 'column', w: 'full', h: 'full' }} sx={{ display: 'flex', flexDir: 'column', w: 'full', h: 'full' }}
> >
<TabList> <TabList>
<Tab>Linear</Tab> <Tab>{t('common.linear')}</Tab>
<Tab>Details</Tab> <Tab>{t('common.details')}</Tab>
<Tab>JSON</Tab> <Tab>JSON</Tab>
</TabList> </TabList>

View File

@ -5,16 +5,9 @@ import { IAISelectDataType } from 'common/components/IAIMantineSearchableSelect'
import IAIMantineSelect from 'common/components/IAIMantineSelect'; import IAIMantineSelect from 'common/components/IAIMantineSelect';
import { setCanvasCoherenceMode } from 'features/parameters/store/generationSlice'; import { setCanvasCoherenceMode } from 'features/parameters/store/generationSlice';
import { CanvasCoherenceModeParam } from 'features/parameters/types/parameterSchemas'; import { CanvasCoherenceModeParam } from 'features/parameters/types/parameterSchemas';
import { memo, useCallback, useMemo } from 'react';
import { memo, useCallback } from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
const coherenceModeSelectData: IAISelectDataType[] = [
{ label: 'Unmasked', value: 'unmasked' },
{ label: 'Mask', value: 'mask' },
{ label: 'Mask Edge', value: 'edge' },
];
const ParamCanvasCoherenceMode = () => { const ParamCanvasCoherenceMode = () => {
const dispatch = useAppDispatch(); const dispatch = useAppDispatch();
const canvasCoherenceMode = useAppSelector( const canvasCoherenceMode = useAppSelector(
@ -22,6 +15,15 @@ const ParamCanvasCoherenceMode = () => {
); );
const { t } = useTranslation(); const { t } = useTranslation();
const coherenceModeSelectData: IAISelectDataType[] = useMemo(
() => [
{ label: t('parameters.unmasked'), value: 'unmasked' },
{ label: t('unifiedCanvas.mask'), value: 'mask' },
{ label: t('parameters.maskEdge'), value: 'edge' },
],
[t]
);
const handleCoherenceModeChange = useCallback( const handleCoherenceModeChange = useCallback(
(v: string | null) => { (v: string | null) => {
if (!v) { if (!v) {

View File

@ -1,20 +1,26 @@
import { Box } from '@chakra-ui/react'; import { Box } from '@chakra-ui/react';
import { useCanvasGenerationMode } from 'features/canvas/hooks/useCanvasGenerationMode'; import { useCanvasGenerationMode } from 'features/canvas/hooks/useCanvasGenerationMode';
import { memo } from 'react'; import { memo, useMemo } from 'react';
import { useTranslation } from 'react-i18next';
const GENERATION_MODE_NAME_MAP = {
txt2img: 'Text to Image',
img2img: 'Image to Image',
inpaint: 'Inpaint',
outpaint: 'Inpaint',
};
const GenerationModeStatusText = () => { const GenerationModeStatusText = () => {
const generationMode = useCanvasGenerationMode(); const generationMode = useCanvasGenerationMode();
const { t } = useTranslation();
const GENERATION_MODE_NAME_MAP = useMemo(
() => ({
txt2img: t('common.txt2img'),
img2img: t('common.img2img'),
inpaint: t('common.inpaint'),
outpaint: t('common.outpaint'),
}),
[t]
);
return ( return (
<Box> <Box>
Mode: {generationMode ? GENERATION_MODE_NAME_MAP[generationMode] : '...'} {t('accessibility.mode')}:{' '}
{generationMode ? GENERATION_MODE_NAME_MAP[generationMode] : '...'}
</Box> </Box>
); );
}; };

View File

@ -7,6 +7,7 @@ import {
ESRGANModelName, ESRGANModelName,
esrganModelNameChanged, esrganModelNameChanged,
} from 'features/parameters/store/postprocessingSlice'; } from 'features/parameters/store/postprocessingSlice';
import { useTranslation } from 'react-i18next';
import { useCallback } from 'react'; import { useCallback } from 'react';
export const ESRGAN_MODEL_NAMES: SelectItem[] = [ export const ESRGAN_MODEL_NAMES: SelectItem[] = [
@ -37,6 +38,8 @@ export const ESRGAN_MODEL_NAMES: SelectItem[] = [
]; ];
export default function ParamESRGANModel() { export default function ParamESRGANModel() {
const { t } = useTranslation();
const esrganModelName = useAppSelector( const esrganModelName = useAppSelector(
(state: RootState) => state.postprocessing.esrganModelName (state: RootState) => state.postprocessing.esrganModelName
); );
@ -50,7 +53,7 @@ export default function ParamESRGANModel() {
return ( return (
<IAIMantineSelect <IAIMantineSelect
label="ESRGAN Model" label={t('models.esrganModel')}
value={esrganModelName} value={esrganModelName}
itemComponent={IAIMantineSelectItemWithTooltip} itemComponent={IAIMantineSelectItemWithTooltip}
onChange={handleChange} onChange={handleChange}

View File

@ -1,8 +1,9 @@
import { Flex, Text } from '@chakra-ui/react'; import { Flex, Text } from '@chakra-ui/react';
import { memo } from 'react'; import { memo } from 'react';
import { COLUMN_WIDTHS } from './constants'; import { COLUMN_WIDTHS } from './constants';
import { useTranslation } from 'react-i18next';
const QueueListHeader = () => { const QueueListHeader = () => {
const { t } = useTranslation();
return ( return (
<Flex <Flex
alignItems="center" alignItems="center"
@ -22,16 +23,16 @@ const QueueListHeader = () => {
<Text variant="subtext">#</Text> <Text variant="subtext">#</Text>
</Flex> </Flex>
<Flex ps={0.5} w={COLUMN_WIDTHS.statusBadge} alignItems="center"> <Flex ps={0.5} w={COLUMN_WIDTHS.statusBadge} alignItems="center">
<Text variant="subtext">status</Text> <Text variant="subtext">{t('queue.status')}</Text>
</Flex> </Flex>
<Flex ps={0.5} w={COLUMN_WIDTHS.time} alignItems="center"> <Flex ps={0.5} w={COLUMN_WIDTHS.time} alignItems="center">
<Text variant="subtext">time</Text> <Text variant="subtext">{t('queue.time')}</Text>
</Flex> </Flex>
<Flex ps={0.5} w={COLUMN_WIDTHS.batchId} alignItems="center"> <Flex ps={0.5} w={COLUMN_WIDTHS.batchId} alignItems="center">
<Text variant="subtext">batch</Text> <Text variant="subtext">{t('queue.batch')}</Text>
</Flex> </Flex>
<Flex ps={0.5} w={COLUMN_WIDTHS.fieldValues} alignItems="center"> <Flex ps={0.5} w={COLUMN_WIDTHS.fieldValues} alignItems="center">
<Text variant="subtext">batch field values</Text> <Text variant="subtext">{t('queue.batchFieldValues')}</Text>
</Flex> </Flex>
</Flex> </Flex>
); );

View File

@ -298,13 +298,13 @@ const SettingsModal = ({ children, config }: SettingsModalProps) => {
<Heading size="sm">{t('settings.generation')}</Heading> <Heading size="sm">{t('settings.generation')}</Heading>
<SettingsSchedulers /> <SettingsSchedulers />
<SettingSwitch <SettingSwitch
label="Enable NSFW Checker" label={t('settings.enableNSFWChecker')}
isDisabled={!isNSFWCheckerAvailable} isDisabled={!isNSFWCheckerAvailable}
isChecked={shouldUseNSFWChecker} isChecked={shouldUseNSFWChecker}
onChange={handleChangeShouldUseNSFWChecker} onChange={handleChangeShouldUseNSFWChecker}
/> />
<SettingSwitch <SettingSwitch
label="Enable Invisible Watermark" label={t('settings.enableInvisibleWatermark')}
isDisabled={!isWatermarkerAvailable} isDisabled={!isWatermarkerAvailable}
isChecked={shouldUseWatermarker} isChecked={shouldUseWatermarker}
onChange={handleChangeShouldUseWatermarker} onChange={handleChangeShouldUseWatermarker}
@ -351,7 +351,7 @@ const SettingsModal = ({ children, config }: SettingsModalProps) => {
/> />
)} )}
<SettingSwitch <SettingSwitch
label="Enable informational popovers" label={t('settings.enableInformationalPopovers')}
isChecked={shouldEnableInformationalPopovers} isChecked={shouldEnableInformationalPopovers}
onChange={handleChangeShouldEnableInformationalPopovers} onChange={handleChangeShouldEnableInformationalPopovers}
/> />

View File

@ -1,6 +1,6 @@
import { Tab, TabList, TabPanel, TabPanels, Tabs } from '@chakra-ui/react'; import { Tab, TabList, TabPanel, TabPanels, Tabs } from '@chakra-ui/react';
import i18n from 'i18n'; import { ReactNode, memo, useMemo } from 'react';
import { ReactNode, memo } from 'react'; import { useTranslation } from 'react-i18next';
import ImportModelsPanel from '../../../../modelManager/subpanels/ImportModelsPanel'; import ImportModelsPanel from '../../../../modelManager/subpanels/ImportModelsPanel';
import MergeModelsPanel from '../../../../modelManager/subpanels/MergeModelsPanel'; import MergeModelsPanel from '../../../../modelManager/subpanels/MergeModelsPanel';
import ModelManagerPanel from '../../../../modelManager/subpanels/ModelManagerPanel'; import ModelManagerPanel from '../../../../modelManager/subpanels/ModelManagerPanel';
@ -18,30 +18,34 @@ type ModelManagerTabInfo = {
content: ReactNode; content: ReactNode;
}; };
const tabs: ModelManagerTabInfo[] = [
{
id: 'modelManager',
label: i18n.t('modelManager.modelManager'),
content: <ModelManagerPanel />,
},
{
id: 'importModels',
label: i18n.t('modelManager.importModels'),
content: <ImportModelsPanel />,
},
{
id: 'mergeModels',
label: i18n.t('modelManager.mergeModels'),
content: <MergeModelsPanel />,
},
{
id: 'settings',
label: i18n.t('modelManager.settings'),
content: <ModelManagerSettingsPanel />,
},
];
const ModelManagerTab = () => { const ModelManagerTab = () => {
const { t } = useTranslation();
const tabs: ModelManagerTabInfo[] = useMemo(
() => [
{
id: 'modelManager',
label: t('modelManager.modelManager'),
content: <ModelManagerPanel />,
},
{
id: 'importModels',
label: t('modelManager.importModels'),
content: <ImportModelsPanel />,
},
{
id: 'mergeModels',
label: t('modelManager.mergeModels'),
content: <MergeModelsPanel />,
},
{
id: 'settings',
label: t('modelManager.settings'),
content: <ModelManagerSettingsPanel />,
},
],
[t]
);
return ( return (
<Tabs <Tabs
isLazy isLazy

View File

@ -6,6 +6,7 @@ import { useDroppableTypesafe } from 'features/dnd/hooks/typesafeHooks';
import { CanvasInitialImageDropData } from 'features/dnd/types'; import { CanvasInitialImageDropData } from 'features/dnd/types';
import { isValidDrop } from 'features/dnd/util/isValidDrop'; import { isValidDrop } from 'features/dnd/util/isValidDrop';
import { memo } from 'react'; import { memo } from 'react';
import { useTranslation } from 'react-i18next';
const droppableData: CanvasInitialImageDropData = { const droppableData: CanvasInitialImageDropData = {
id: 'canvas-intial-image', id: 'canvas-intial-image',
@ -13,6 +14,7 @@ const droppableData: CanvasInitialImageDropData = {
}; };
const UnifiedCanvasContent = () => { const UnifiedCanvasContent = () => {
const { t } = useTranslation();
const { const {
isOver, isOver,
setNodeRef: setDroppableRef, setNodeRef: setDroppableRef,
@ -40,7 +42,10 @@ const UnifiedCanvasContent = () => {
<IAICanvasToolbar /> <IAICanvasToolbar />
<IAICanvas /> <IAICanvas />
{isValidDrop(droppableData, active) && ( {isValidDrop(droppableData, active) && (
<IAIDropOverlay isOver={isOver} label="Set Canvas Initial Image" /> <IAIDropOverlay
isOver={isOver}
label={t('toast.setCanvasInitialImage')}
/>
)} )}
</Flex> </Flex>
); );