Skip to content

Commit ee4bc49

Browse files
hipsterusernamepsychedelicious
authored andcommitted
Prettier.
1 parent 188cf37 commit ee4bc49

File tree

3 files changed

+143
-130
lines changed

3 files changed

+143
-130
lines changed

invokeai/frontend/web/public/locales/en.json

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -815,7 +815,8 @@
815815
"inplaceInstall": "In-place install",
816816
"inplaceInstallDesc": "Install models without copying the files. When using the model, it will be loaded from its this location. If disabled, the model file(s) will be copied into the Invoke-managed models directory during installation.",
817817
"install": "Install",
818-
"installAll": "Install All", "installRepo": "Install Repo",
818+
"installAll": "Install All",
819+
"installRepo": "Install Repo",
819820
"ipAdapters": "IP Adapters",
820821
"learnMoreAboutSupportedModels": "Learn more about the models we support",
821822
"load": "Load",
@@ -869,7 +870,8 @@
869870
"sigLip": "SigLIP",
870871
"spandrelImageToImage": "Image to Image (Spandrel)",
871872
"starterBundles": "Starter Bundles",
872-
"starterBundleHelpText": "Easily install all models needed to get started with a base model, including a main model, controlnets, IP adapters, and more. Selecting a bundle will skip any models that you already have installed.", "starterModels": "Starter Models",
873+
"starterBundleHelpText": "Easily install all models needed to get started with a base model, including a main model, controlnets, IP adapters, and more. Selecting a bundle will skip any models that you already have installed.",
874+
"starterModels": "Starter Models",
873875
"starterModelsInModelManager": "Starter Models can be found in Model Manager",
874876
"launchpadTab": "Launchpad",
875877
"launchpad": {
@@ -878,7 +880,8 @@
878880
"manualInstall": "Manual Installation",
879881
"urlDescription": "Install models from a URL or local file path. Perfect for specific models you want to add.",
880882
"huggingFaceDescription": "Browse and install models directly from HuggingFace repositories.",
881-
"scanFolderDescription": "Scan a local folder to automatically detect and install models.", "recommendedModels": "Recommended Models",
883+
"scanFolderDescription": "Scan a local folder to automatically detect and install models.",
884+
"recommendedModels": "Recommended Models",
882885
"exploreStarter": "Browse all available starter models",
883886
"quickStart": "Quick Start Bundles",
884887
"bundleDescription": "Each bundle includes essential models for each model family and curated base models to get started",

invokeai/frontend/web/src/features/modelManagerV2/subpanels/AddModelPanel/LaunchpadForm/LaunchpadForm.tsx

Lines changed: 131 additions & 125 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { flatMap, negate, uniqWith } from 'lodash-es';
77
import { memo, useCallback } from 'react';
88
import { useTranslation } from 'react-i18next';
99
import { PiFolderOpenBold, PiLinkBold, PiStarBold } from 'react-icons/pi';
10-
import { SiHuggingface } from "react-icons/si";
10+
import { SiHuggingface } from 'react-icons/si';
1111
import { useGetStarterModelsQuery, useInstallModelMutation } from 'services/api/endpoints/models';
1212

1313
export const LaunchpadForm = memo(() => {
@@ -16,49 +16,52 @@ export const LaunchpadForm = memo(() => {
1616
const { getIsInstalled, buildModelInstallArg } = useBuildModelInstallArg();
1717
const { data: starterModelsData } = useGetStarterModelsQuery();
1818
// Function to install models from a bundle
19-
const installBundle = useCallback((bundleName: string) => {
20-
if (!starterModelsData?.starter_bundles) {
21-
return;
22-
}
23-
24-
const bundle = starterModelsData.starter_bundles[bundleName];
25-
if (!bundle) {
26-
return;
27-
}
19+
const installBundle = useCallback(
20+
(bundleName: string) => {
21+
if (!starterModelsData?.starter_bundles) {
22+
return;
23+
}
2824

29-
// Flatten the models and remove duplicates, which is expected as models can have the same dependencies
30-
const flattenedModels = flatMap(bundle, flattenStarterModel);
31-
const uniqueModels = uniqWith(
32-
flattenedModels,
33-
(m1, m2) => m1.source === m2.source || (m1.name === m2.name && m1.base === m2.base && m1.type === m2.type)
34-
);
35-
// We want to install models that are not installed and skip models that are already installed
36-
const install = uniqueModels.filter(negate(getIsInstalled)).map(buildModelInstallArg);
37-
const skip = uniqueModels.filter(getIsInstalled).map(buildModelInstallArg);
25+
const bundle = starterModelsData.starter_bundles[bundleName];
26+
if (!bundle) {
27+
return;
28+
}
29+
30+
// Flatten the models and remove duplicates, which is expected as models can have the same dependencies
31+
const flattenedModels = flatMap(bundle, flattenStarterModel);
32+
const uniqueModels = uniqWith(
33+
flattenedModels,
34+
(m1, m2) => m1.source === m2.source || (m1.name === m2.name && m1.base === m2.base && m1.type === m2.type)
35+
);
36+
// We want to install models that are not installed and skip models that are already installed
37+
const install = uniqueModels.filter(negate(getIsInstalled)).map(buildModelInstallArg);
38+
const skip = uniqueModels.filter(getIsInstalled).map(buildModelInstallArg);
39+
40+
if (install.length === 0) {
41+
toast({
42+
status: 'info',
43+
title: t('modelManager.bundleAlreadyInstalled', { bundleName }),
44+
description: t('modelManager.allModelsAlreadyInstalled'),
45+
});
46+
return;
47+
}
48+
49+
// Install all models in the bundle
50+
install.forEach(installModel);
51+
52+
let description = t('modelManager.installingXModels', { count: install.length });
53+
if (skip.length > 1) {
54+
description += t('modelManager.skippingXDuplicates', { count: skip.length - 1 });
55+
}
3856

39-
if (install.length === 0) {
4057
toast({
4158
status: 'info',
42-
title: t('modelManager.bundleAlreadyInstalled', { bundleName }),
43-
description: t('modelManager.allModelsAlreadyInstalled'),
59+
title: t('modelManager.installingBundle'),
60+
description,
4461
});
45-
return;
46-
}
47-
48-
// Install all models in the bundle
49-
install.forEach(installModel);
50-
51-
let description = t('modelManager.installingXModels', { count: install.length });
52-
if (skip.length > 1) {
53-
description += t('modelManager.skippingXDuplicates', { count: skip.length - 1 });
54-
}
55-
56-
toast({
57-
status: 'info',
58-
title: t('modelManager.installingBundle'),
59-
description,
60-
});
61-
}, [starterModelsData, getIsInstalled, buildModelInstallArg, installModel, t]);
62+
},
63+
[starterModelsData, getIsInstalled, buildModelInstallArg, installModel, t]
64+
);
6265

6366
const navigateToUrlTab = useCallback(() => {
6467
$installModelsTab.set(1); // URL/Local Path tab (now index 1)
@@ -71,7 +74,7 @@ export const LaunchpadForm = memo(() => {
7174
const navigateToScanFolderTab = useCallback(() => {
7275
$installModelsTab.set(3); // Scan Folder tab (now index 3)
7376
}, []);
74-
77+
7578
const navigateToStarterModelsTab = useCallback(() => {
7679
$installModelsTab.set(4); // Starter Models tab (now index 4)
7780
}, []);
@@ -85,90 +88,91 @@ export const LaunchpadForm = memo(() => {
8588

8689
const handleFluxBundleClick = useCallback(() => {
8790
installBundle('flux');
88-
}, [installBundle]); return (
91+
}, [installBundle]);
92+
return (
8993
<Flex flexDir="column" height="100%" gap={3}>
9094
<ScrollableContent>
9195
<Flex flexDir="column" gap={6} p={3}>
92-
{/* Welcome Section */}
93-
<Box>
94-
<Heading size="md" mb={1}>
95-
{t('modelManager.launchpad.welcome')}
96-
</Heading>
97-
<Text color="base.300" fontSize="sm">
98-
{t('modelManager.launchpad.description')}
99-
</Text>
100-
</Box>
101-
102-
{/* Manual Installation Options */}
103-
<Box>
104-
<Heading size="sm" mb={2}>
105-
{t('modelManager.launchpad.manualInstall')}
106-
</Heading> <Grid templateColumns="repeat(auto-fit, minmax(280px, 1fr))" gap={3}>
107-
<LaunchpadCard
108-
title={t('modelManager.urlOrLocalPath')}
109-
description={t('modelManager.launchpad.urlDescription')}
110-
icon={<PiLinkBold size={24} />}
111-
onClick={navigateToUrlTab}
112-
/>
113-
<LaunchpadCard
114-
title={t('modelManager.huggingFace')}
115-
description={t('modelManager.launchpad.huggingFaceDescription')}
116-
icon={<SiHuggingface size={24} />}
117-
onClick={navigateToHuggingFaceTab}
118-
/>
119-
<LaunchpadCard
120-
title={t('modelManager.scanFolder')}
121-
description={t('modelManager.launchpad.scanFolderDescription')}
122-
icon={<PiFolderOpenBold size={24} />}
123-
onClick={navigateToScanFolderTab}
124-
/>
125-
</Grid>
126-
</Box> {/* Recommended Section */}
127-
<Box>
128-
<Heading size="sm" mb={2}>
129-
{t('modelManager.launchpad.recommendedModels')}
130-
</Heading>
131-
<Flex flexDir="column" gap={2}> {/* Starter Model Bundles - More Prominent */}
96+
{/* Welcome Section */}
13297
<Box>
133-
<Heading size="xs" color="base.100" mb={1}>
134-
{t('modelManager.launchpad.quickStart')}
98+
<Heading size="md" mb={1}>
99+
{t('modelManager.launchpad.welcome')}
135100
</Heading>
136-
<Text fontSize="xs" color="base.300" mb={2}>
137-
{t('modelManager.launchpad.bundleDescription')}
138-
</Text> <Grid templateColumns="repeat(auto-fit, minmax(180px, 1fr))" gap={2}>
139-
<LaunchpadBundleCard
140-
title="Stable Diffusion 1.5"
141-
onClick={handleSD15BundleClick}
101+
<Text color="base.300" fontSize="sm">
102+
{t('modelManager.launchpad.description')}
103+
</Text>
104+
</Box>
105+
{/* Manual Installation Options */}
106+
<Box>
107+
<Heading size="sm" mb={2}>
108+
{t('modelManager.launchpad.manualInstall')}
109+
</Heading>{' '}
110+
<Grid templateColumns="repeat(auto-fit, minmax(280px, 1fr))" gap={3}>
111+
<LaunchpadCard
112+
title={t('modelManager.urlOrLocalPath')}
113+
description={t('modelManager.launchpad.urlDescription')}
114+
icon={<PiLinkBold size={24} />}
115+
onClick={navigateToUrlTab}
142116
/>
143-
<LaunchpadBundleCard
144-
title="SDXL"
145-
onClick={handleSDXLBundleClick}
117+
<LaunchpadCard
118+
title={t('modelManager.huggingFace')}
119+
description={t('modelManager.launchpad.huggingFaceDescription')}
120+
icon={<SiHuggingface size={24} />}
121+
onClick={navigateToHuggingFaceTab}
146122
/>
147-
<LaunchpadBundleCard
148-
title="FLUX.1 [dev]"
149-
onClick={handleFluxBundleClick}
123+
<LaunchpadCard
124+
title={t('modelManager.scanFolder')}
125+
description={t('modelManager.launchpad.scanFolderDescription')}
126+
icon={<PiFolderOpenBold size={24} />}
127+
onClick={navigateToScanFolderTab}
150128
/>
151129
</Grid>
152-
</Box> {/* Browse All - Simple Link */}
153-
<Box pt={1} borderTop="1px solid" borderColor="base.700">
154-
<Text fontSize="xs" color="base.400" mb={1}>
155-
{t('modelManager.launchpad.browseAll')}
156-
</Text>
157-
<Button
158-
onClick={navigateToStarterModelsTab}
159-
variant="link" color="invokeBlue.300"
160-
fontSize="sm"
161-
fontWeight="medium"
162-
p={0}
163-
h="auto"
164-
leftIcon={<PiStarBold size={16} />}
165-
_hover={{
166-
color: "invokeBlue.200",
167-
textDecoration: "underline"
168-
}}
169-
>
170-
{t('modelManager.launchpad.exploreStarter')}
171-
</Button> </Box> </Flex> </Box>
130+
</Box>{' '}
131+
{/* Recommended Section */}
132+
<Box>
133+
<Heading size="sm" mb={2}>
134+
{t('modelManager.launchpad.recommendedModels')}
135+
</Heading>
136+
<Flex flexDir="column" gap={2}>
137+
{' '}
138+
{/* Starter Model Bundles - More Prominent */}
139+
<Box>
140+
<Heading size="xs" color="base.100" mb={1}>
141+
{t('modelManager.launchpad.quickStart')}
142+
</Heading>
143+
<Text fontSize="xs" color="base.300" mb={2}>
144+
{t('modelManager.launchpad.bundleDescription')}
145+
</Text>{' '}
146+
<Grid templateColumns="repeat(auto-fit, minmax(180px, 1fr))" gap={2}>
147+
<LaunchpadBundleCard title="Stable Diffusion 1.5" onClick={handleSD15BundleClick} />
148+
<LaunchpadBundleCard title="SDXL" onClick={handleSDXLBundleClick} />
149+
<LaunchpadBundleCard title="FLUX.1 [dev]" onClick={handleFluxBundleClick} />
150+
</Grid>
151+
</Box>{' '}
152+
{/* Browse All - Simple Link */}
153+
<Box pt={1} borderTop="1px solid" borderColor="base.700">
154+
<Text fontSize="xs" color="base.400" mb={1}>
155+
{t('modelManager.launchpad.browseAll')}
156+
</Text>
157+
<Button
158+
onClick={navigateToStarterModelsTab}
159+
variant="link"
160+
color="invokeBlue.300"
161+
fontSize="sm"
162+
fontWeight="medium"
163+
p={0}
164+
h="auto"
165+
leftIcon={<PiStarBold size={16} />}
166+
_hover={{
167+
color: 'invokeBlue.200',
168+
textDecoration: 'underline',
169+
}}
170+
>
171+
{t('modelManager.launchpad.exploreStarter')}
172+
</Button>{' '}
173+
</Box>{' '}
174+
</Flex>{' '}
175+
</Box>
172176
</Flex>
173177
</ScrollableContent>
174178
</Flex>
@@ -186,7 +190,8 @@ interface LaunchpadCardProps {
186190
}
187191

188192
const LaunchpadCard = memo(({ title, description, icon, onClick, variant = 'default' }: LaunchpadCardProps) => {
189-
return ( <Button
193+
return (
194+
<Button
190195
onClick={onClick}
191196
variant="outline"
192197
h="auto"
@@ -221,9 +226,9 @@ const LaunchpadCard = memo(({ title, description, icon, onClick, variant = 'defa
221226
{title}
222227
</Heading>
223228
</Flex>
224-
<Text
225-
fontSize="sm"
226-
color={variant === 'featured' ? 'invokeBlue.200' : 'base.400'}
229+
<Text
230+
fontSize="sm"
231+
color={variant === 'featured' ? 'invokeBlue.200' : 'base.400'}
227232
lineHeight="1.4"
228233
flex="1"
229234
whiteSpace="normal"
@@ -254,19 +259,20 @@ const LaunchpadBundleCard = memo(({ title, onClick }: LaunchpadBundleCardProps)
254259
borderColor="invokeBlue.400"
255260
bg="invokeBlue.950"
256261
_hover={{
257-
bg: "invokeBlue.900",
258-
borderColor: "invokeBlue.300",
259-
transform: "translateY(-2px)",
260-
boxShadow: "0 4px 20px rgba(66, 153, 225, 0.15)",
262+
bg: 'invokeBlue.900',
263+
borderColor: 'invokeBlue.300',
264+
transform: 'translateY(-2px)',
265+
boxShadow: '0 4px 20px rgba(66, 153, 225, 0.15)',
261266
}}
262267
_active={{
263-
transform: "translateY(0px)",
268+
transform: 'translateY(0px)',
264269
}}
265270
transition="all 0.2s"
266271
cursor="pointer"
267272
textAlign="center"
268273
justifyContent="center"
269-
alignItems="center" borderRadius="lg"
274+
alignItems="center"
275+
borderRadius="lg"
270276
whiteSpace="normal"
271277
>
272278
<Text fontSize="sm" fontWeight="bold" color="invokeBlue.100" noOfLines={1}>

invokeai/frontend/web/src/features/modelManagerV2/subpanels/InstallModels.tsx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,17 @@ export const InstallModels = memo(() => {
3030
<Button alignItems="center" variant="link" leftIcon={<PiInfoBold />} onClick={onClickLearnMore}>
3131
<Text variant="subtext">{t('modelManager.learnMoreAboutSupportedModels')}</Text>
3232
</Button>
33-
</Flex> <Tabs variant="collapse" height="50%" display="flex" flexDir="column" index={index} onChange={onChange}> <TabList>
33+
</Flex>{' '}
34+
<Tabs variant="collapse" height="50%" display="flex" flexDir="column" index={index} onChange={onChange}>
35+
{' '}
36+
<TabList>
3437
<Tab>{t('modelManager.launchpadTab')}</Tab>
3538
<Tab>{t('modelManager.urlOrLocalPath')}</Tab>
3639
<Tab>{t('modelManager.huggingFace')}</Tab>
3740
<Tab>{t('modelManager.scanFolder')}</Tab>
3841
<Tab>{t('modelManager.starterModels')}</Tab>
39-
</TabList> <TabPanels p={3} height="100%">
42+
</TabList>{' '}
43+
<TabPanels p={3} height="100%">
4044
<TabPanel height="100%">
4145
<LaunchpadForm />
4246
</TabPanel>

0 commit comments

Comments
 (0)