mirror of
https://github.com/invoke-ai/InvokeAI.git
synced 2026-01-15 06:18:03 -05:00
Compare commits
3 Commits
v5.9.1
...
maryhipp/w
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f8ccf78af4 | ||
|
|
b91738596a | ||
|
|
4f592ca79f |
@@ -2073,5 +2073,16 @@
|
||||
"metadata": "Metadata"
|
||||
},
|
||||
"showSendingToAlerts": "Alert When Sending to Different View"
|
||||
},
|
||||
"whatsNew": {
|
||||
"whatsNewInInvoke": "What's New in Invoke",
|
||||
"canvasV2Announcement": {
|
||||
"newCanvas": "A powerful new control canvas",
|
||||
"newLayerTypes": "New layer types for even more control",
|
||||
"fluxSupport": "Support for the Flux family of models",
|
||||
"readReleaseNotes": "Read Release Notes",
|
||||
"watchReleaseVideo": "Watch Release Video",
|
||||
"watchUiUpdatesOverview": "Watch UI Updates Overview"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
import { Flex, Icon, ListItem, Text, UnorderedList } from '@invoke-ai/ui-library';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { PiArrowSquareOutBold } from 'react-icons/pi';
|
||||
|
||||
export const CanvasV2Announcement = () => {
|
||||
const { t } = useTranslation();
|
||||
return (
|
||||
<Flex gap={4} flexDir="column">
|
||||
<UnorderedList fontSize="sm">
|
||||
<ListItem>{t('whatsNew.canvasV2Announcement.newCanvas')}</ListItem>
|
||||
<ListItem>{t('whatsNew.canvasV2Announcement.newLayerTypes')}</ListItem>
|
||||
<ListItem>{t('whatsNew.canvasV2Announcement.fluxSupport')}</ListItem>
|
||||
</UnorderedList>
|
||||
<Flex flexDir="column" gap={1}>
|
||||
<Flex gap={2}>
|
||||
<Text as="a" target="_blank" href="https://github.com/invoke-ai/InvokeAI/releases" fontWeight="semibold">
|
||||
{t('whatsNew.canvasV2Announcement.readReleaseNotes')}
|
||||
</Text>
|
||||
<Icon as={PiArrowSquareOutBold} />
|
||||
</Flex>
|
||||
<Flex gap={2}>
|
||||
<Text as="a" target="_blank" href="https://www.youtube.com/@invokeai/videos" fontWeight="semibold">
|
||||
{t('whatsNew.canvasV2Announcement.watchReleaseVideo')}
|
||||
</Text>
|
||||
<Icon as={PiArrowSquareOutBold} />
|
||||
</Flex>
|
||||
<Flex gap={2}>
|
||||
<Text as="a" target="_blank" href="https://www.youtube.com/@invokeai/videos" fontWeight="semibold">
|
||||
{t('whatsNew.canvasV2Announcement.watchUiUpdatesOverview')}
|
||||
</Text>
|
||||
<Icon as={PiArrowSquareOutBold} />
|
||||
</Flex>
|
||||
</Flex>
|
||||
</Flex>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,67 @@
|
||||
import {
|
||||
Box,
|
||||
Flex,
|
||||
IconButton,
|
||||
Image,
|
||||
Popover,
|
||||
PopoverBody,
|
||||
PopoverCloseButton,
|
||||
PopoverContent,
|
||||
PopoverHeader,
|
||||
PopoverTrigger,
|
||||
} from '@invoke-ai/ui-library';
|
||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||
import { shouldShowNotificationIndicatorChanged } from 'features/ui/store/uiSlice';
|
||||
import InvokeSymbol from 'public/assets/images/invoke-favicon.png';
|
||||
import { useCallback } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { PiLightbulbFilamentBold } from 'react-icons/pi';
|
||||
|
||||
import { CanvasV2Announcement } from './CanvasV2Announcement';
|
||||
|
||||
export const Notifications = () => {
|
||||
const { t } = useTranslation();
|
||||
const dispatch = useAppDispatch();
|
||||
const shouldShowNotificationIndicator = useAppSelector((s) => s.ui.shouldShowNotificationIndicator);
|
||||
const resetIndicator = useCallback(() => {
|
||||
dispatch(shouldShowNotificationIndicatorChanged(false));
|
||||
}, [dispatch]);
|
||||
|
||||
return (
|
||||
<Popover onOpen={resetIndicator} placement="top-start">
|
||||
<PopoverTrigger>
|
||||
<Flex pos="relative">
|
||||
<IconButton
|
||||
aria-label="Notifications"
|
||||
variant="link"
|
||||
icon={<PiLightbulbFilamentBold fontSize={20} />}
|
||||
boxSize={8}
|
||||
/>
|
||||
{shouldShowNotificationIndicator && (
|
||||
<Box
|
||||
pos="absolute"
|
||||
top={0}
|
||||
right="2px"
|
||||
w={2}
|
||||
h={2}
|
||||
backgroundColor="invokeYellow.500"
|
||||
borderRadius="100%"
|
||||
/>
|
||||
)}
|
||||
</Flex>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent>
|
||||
<PopoverCloseButton />
|
||||
<PopoverHeader fontSize="md" fontWeight="semibold">
|
||||
<Flex alignItems="center" gap={3}>
|
||||
<Image src={InvokeSymbol} boxSize={6} />
|
||||
{t('whatsNew.whatsNewInInvoke')}
|
||||
</Flex>
|
||||
</PopoverHeader>
|
||||
<PopoverBody p={2}>
|
||||
<CanvasV2Announcement />
|
||||
</PopoverBody>
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
);
|
||||
};
|
||||
@@ -9,6 +9,7 @@ import { memo } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { PiBoundingBoxBold, PiCubeBold, PiFlowArrowBold, PiFrameCornersBold, PiQueueBold } from 'react-icons/pi';
|
||||
|
||||
import { Notifications } from './Notifications';
|
||||
import { TabButton } from './TabButton';
|
||||
|
||||
export const VerticalNavBar = memo(() => {
|
||||
@@ -37,6 +38,7 @@ export const VerticalNavBar = memo(() => {
|
||||
</Flex>
|
||||
<Spacer />
|
||||
<StatusIndicator />
|
||||
<Notifications />
|
||||
{customNavComponent ? customNavComponent : <SettingsMenu />}
|
||||
</Flex>
|
||||
);
|
||||
|
||||
@@ -13,6 +13,7 @@ const initialUIState: UIState = {
|
||||
shouldShowProgressInViewer: true,
|
||||
accordions: {},
|
||||
expanders: {},
|
||||
shouldShowNotificationIndicator: true,
|
||||
};
|
||||
|
||||
export const uiSlice = createSlice({
|
||||
@@ -36,6 +37,9 @@ export const uiSlice = createSlice({
|
||||
const { id, isOpen } = action.payload;
|
||||
state.expanders[id] = isOpen;
|
||||
},
|
||||
shouldShowNotificationIndicatorChanged: (state, action: PayloadAction<boolean>) => {
|
||||
state.shouldShowNotificationIndicator = action.payload;
|
||||
},
|
||||
},
|
||||
extraReducers(builder) {
|
||||
builder.addCase(workflowLoadRequested, (state) => {
|
||||
@@ -50,6 +54,7 @@ export const {
|
||||
setShouldShowProgressInViewer,
|
||||
accordionStateChanged,
|
||||
expanderStateChanged,
|
||||
shouldShowNotificationIndicatorChanged,
|
||||
} = uiSlice.actions;
|
||||
|
||||
export const selectUiSlice = (state: RootState) => state.ui;
|
||||
|
||||
@@ -25,4 +25,8 @@ export interface UIState {
|
||||
* The state of expanders. The key is the id of the expander, and the value is a boolean representing the open state.
|
||||
*/
|
||||
expanders: Record<string, boolean>;
|
||||
/**
|
||||
* Whether or not to show the user an indicator on notifications icon.
|
||||
*/
|
||||
shouldShowNotificationIndicator: boolean;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user