Nav: functions for nav/icon visibility #356

This commit is contained in:
Enrico Ros
2024-01-22 15:53:34 -08:00
parent 1ed86b6ebc
commit 695af02cee
8 changed files with 107 additions and 69 deletions
@@ -48,7 +48,7 @@ import { parseBlocks } from './blocks';
// How long is the user collapsed message
const USER_COLLAPSED_LINES: number = 8;
// Enable the automatic menu on text selection
// Enable the menu on text selection
const ENABLE_SELECTION_RIGHT_CLICK_MENU: boolean = true;
// Enable the hover button to copy the whole message. The Copy button is also available in Blocks, or in the Avatar Menu.
+50 -26
View File
@@ -13,13 +13,14 @@ import EventNoteIcon from '@mui/icons-material/EventNote';
import EventNoteOutlinedIcon from '@mui/icons-material/EventNoteOutlined';
import FormatPaintIcon from '@mui/icons-material/FormatPaint';
import FormatPaintOutlinedIcon from '@mui/icons-material/FormatPaintOutlined';
import ImageIcon from '@mui/icons-material/Image';
import ImageOutlinedIcon from '@mui/icons-material/ImageOutlined';
import IosShareIcon from '@mui/icons-material/IosShare';
import IosShareOutlinedIcon from '@mui/icons-material/IosShareOutlined';
import TextsmsIcon from '@mui/icons-material/Textsms';
import TextsmsOutlinedIcon from '@mui/icons-material/TextsmsOutlined';
import WorkspacesIcon from '@mui/icons-material/Workspaces';
import WorkspacesOutlinedIcon from '@mui/icons-material/WorkspacesOutlined';
// Automatic apps
import ImageOutlinedIcon from '@mui/icons-material/ImageOutlined';
import IosShareIcon from '@mui/icons-material/IosShare';
// Link icons
import GitHubIcon from '@mui/icons-material/GitHub';
import { DiscordIcon } from '~/common/components/icons/DiscordIcon';
@@ -29,11 +30,14 @@ import SettingsIcon from '@mui/icons-material/Settings';
import { Brand } from '~/common/app.config';
import { hasNoChatLinkItems } from '~/modules/trade/chatlink/store-chatlink';
// enable to show all items, for layout development
const SHOW_ALL_APPS = false;
const SPECIAL_DIVIDER = '__DIVIDER__';
// Nav items
@@ -47,12 +51,14 @@ interface ItemBase {
export interface NavItemApp extends ItemBase {
type: 'app',
route: string,
landingRoute?: string, // specify a different route than the nextjs page router route, to land to
barTitle?: string, // set to override the name as the bar title (unless custom bar content is used)
hideIcon?: boolean
| (() => boolean), // set to true to hide the icon, unless this is the active app
hideBar?: boolean, // set to true to hide the page bar
hideDrawer?: boolean, // set to true to hide the drawer
hideNav?: boolean, // set to hide the Nav bar (note: must have a way to navigate back)
hideOnMobile?: boolean, // set to true to hide on mobile
automatic?: boolean, // only accessible by the machine
hideNav?: boolean
| (() => boolean), // set to hide the Nav bar (note: must have a way to navigate back)
fullWidth?: boolean, // set to true to override the user preference
_delete?: boolean, // delete from the UI
}
@@ -131,6 +137,13 @@ export const navItems: {
route: '/workspace',
_delete: true,
},
// <-- divider here -->
{
name: SPECIAL_DIVIDER,
type: 'app',
route: SPECIAL_DIVIDER,
icon: () => null,
},
{
name: 'Personas',
icon: Diversity2OutlinedIcon,
@@ -139,6 +152,24 @@ export const navItems: {
route: '/personas',
hideBar: true,
},
{
name: 'Media Library',
icon: ImageOutlinedIcon,
iconActive: ImageIcon,
type: 'app',
route: '/media',
_delete: true,
},
{
name: 'Shared Chat',
icon: IosShareOutlinedIcon,
iconActive: IosShareIcon,
type: 'app',
route: '/link/chat/[chatLinkId]',
landingRoute: '/link/chat/list',
hideIcon: hasNoChatLinkItems,
hideNav: hasNoChatLinkItems,
},
{
name: 'News',
icon: EventNoteOutlinedIcon,
@@ -148,25 +179,6 @@ export const navItems: {
hideBar: true,
hideDrawer: true,
},
// non-user-selectable ('automatic') Apps
{
name: 'Media Library',
icon: ImageOutlinedIcon,
type: 'app',
route: '/media',
automatic: true,
hideNav: true,
_delete: true,
},
{
name: 'Shared Chat',
icon: IosShareIcon,
type: 'app',
route: '/link/chat/[chatLinkId]',
automatic: true,
hideNav: true,
},
],
// Modals
@@ -210,4 +222,16 @@ export const navItems: {
};
// apply UI filtering right away - do it here, once, and for all
navItems.apps = navItems.apps.filter(app => !app._delete || SHOW_ALL_APPS);
navItems.apps = navItems.apps.filter(app => !app._delete || SHOW_ALL_APPS);
export function checkDivider(app?: NavItemApp) {
return app?.name === SPECIAL_DIVIDER;
}
export function checkVisibileIcon(app: NavItemApp, currentApp?: NavItemApp) {
return app === currentApp ? true : typeof app.hideIcon === 'function' ? !app.hideIcon() : !app.hideIcon;
}
export function checkVisibleNav(app?: NavItemApp) {
return !app ? false : typeof app.hideNav === 'function' ? !app.hideNav() : !app.hideNav;
}
+2 -2
View File
@@ -2,7 +2,7 @@ import * as React from 'react';
import { Box, Sheet, styled } from '@mui/joy';
import type { NavItemApp } from '~/common/app.nav';
import { checkVisibleNav, NavItemApp } from '~/common/app.nav';
import { themeZIndexDesktopDrawer } from '~/common/app.theme';
import { useOptimaDrawers } from './useOptimaDrawers';
@@ -81,7 +81,7 @@ export function DesktopDrawer(props: { currentApp?: NavItemApp }) {
}, [closeDrawer, currentAppUsesDrawer]);
// [special case] remove in the future
const shallOpenNavForSharedLink = !props.currentApp?.hideDrawer && !!props.currentApp?.hideNav;
const shallOpenNavForSharedLink = !props.currentApp?.hideDrawer && checkVisibleNav(props.currentApp);
React.useEffect(() => {
if (shallOpenNavForSharedLink)
openDrawer();
+24 -22
View File
@@ -7,7 +7,7 @@ import MenuIcon from '@mui/icons-material/Menu';
import { useModelsStore } from '~/modules/llms/store-llms';
import { AgiSquircleIcon } from '~/common/components/icons/AgiSquircleIcon';
import { NavItemApp, navItems } from '~/common/app.nav';
import { checkDivider, checkVisibileIcon, NavItemApp, navItems } from '~/common/app.nav';
import { themeZIndexDesktopNav } from '~/common/app.theme';
import { BringTheLove } from './components/BringTheLove';
@@ -47,27 +47,29 @@ export function DesktopNav(props: { currentApp?: NavItemApp }) {
// App items
const navAppItems = React.useMemo(() => {
return navItems.apps.filter(app => !app.hideNav).map(item => {
const isActive = item === props.currentApp;
const isDrawerable = isActive && !item.hideDrawer;
const isPaneOpen = isDrawerable && isDrawerOpen;
const isNotForUser = !!item.automatic && !isActive;
return (
<Tooltip disableInteractive enterDelay={600} key={'n-m-' + item.route.slice(1)} title={item.name}>
<DesktopNavIcon
disabled={isNotForUser}
variant={isActive ? 'solid' : undefined}
onClick={isDrawerable ? toggleDrawer : () => Router.push(item.route)}
className={`${navItemClasses.typeApp} ${isActive ? navItemClasses.active : ''} ${isPaneOpen ? navItemClasses.paneOpen : ''}`}
>
{/*{(isActive && item.iconActive) ? <item.iconActive /> : <item.icon />}*/}
<item.icon />
</DesktopNavIcon>
</Tooltip>
);
})
// (disabled) add this code after the map to add a divider
.toSpliced(-2, 0, <Divider sx={{ my: 1, width: '50%', mx: 'auto' }} />);
return navItems.apps
.filter(_app => checkVisibileIcon(_app, props.currentApp))
.map((app, appIdx) => {
const isActive = app === props.currentApp;
const isDrawerable = isActive && !app.hideDrawer;
const isPaneOpen = isDrawerable && isDrawerOpen;
if (checkDivider(app))
return <Divider key={'div-' + appIdx} sx={{ my: 1, width: '50%', mx: 'auto' }} />;
return (
<Tooltip key={'n-m-' + app.route.slice(1)} disableInteractive enterDelay={600} title={app.name}>
<DesktopNavIcon
variant={isActive ? 'solid' : undefined}
onClick={isDrawerable ? toggleDrawer : () => Router.push(app.landingRoute || app.route)}
className={`${navItemClasses.typeApp} ${isActive ? navItemClasses.active : ''} ${isPaneOpen ? navItemClasses.paneOpen : ''}`}
>
{/*{(isActive && app.iconActive) ? <app.iconActive /> : <app.icon />}*/}
<app.icon />
</DesktopNavIcon>
</Tooltip>
);
});
}, [props.currentApp, isDrawerOpen, toggleDrawer]);
+24 -13
View File
@@ -1,8 +1,8 @@
import * as React from 'react';
import Router from 'next/router';
import { Button, ButtonGroup, ListItem } from '@mui/joy';
import { Button, ButtonGroup, ListItem, Tooltip } from '@mui/joy';
import { NavItemApp, navItems } from '~/common/app.nav';
import { checkDivider, checkVisibileIcon, NavItemApp, navItems } from '~/common/app.nav';
import { BringTheLove } from './components/BringTheLove';
@@ -27,17 +27,28 @@ export function MobileNavListItem(props: { currentApp?: NavItemApp }) {
gap: 1,
}}
>
{navItems.apps.filter(app => !app.hideOnMobile && !app.hideNav).map(app =>
<Button
key={'app-' + app.name}
disabled={!!app.automatic}
size='sm'
variant={app == props.currentApp ? 'soft' : 'solid'}
onClick={() => Router.push(app.route)}
>
{app == props.currentApp ? app.name : <app.icon />}
</Button>,
)}
{navItems.apps
.filter(app => checkVisibileIcon(app))
.map((app, appIdx) => {
const isActive = app === props.currentApp;
if (checkDivider(app))
return null;
// return <Divider orientation='vertical' key={'div-' + appIdx} />;
return (
<Tooltip key={'n-m-' + app.route.slice(1)} disableInteractive enterDelay={600} title={app.name}>
<Button
key={'app-' + app.name}
size='sm'
variant={isActive ? 'soft' : 'solid'}
onClick={() => Router.push(app.landingRoute || app.route)}
>
{isActive ? app.name : <app.icon />}
</Button>
</Tooltip>
);
})}
</ButtonGroup>
{/* Group 2: Social Links */}
+2 -2
View File
@@ -2,7 +2,7 @@ import * as React from 'react';
import { useRouter } from 'next/router';
import { PanelGroup } from 'react-resizable-panels';
import { navItems } from '~/common/app.nav';
import { checkVisibleNav, navItems } from '~/common/app.nav';
import { useIsMobile } from '~/common/components/useMatchMedia';
import { DesktopDrawer } from './DesktopDrawer';
@@ -50,7 +50,7 @@ export function OptimaLayout(props: { suspendAutoModelsSetup?: boolean, children
<PanelGroup direction='horizontal' id='desktop-layout'>
{!currentApp?.hideNav && <DesktopNav currentApp={currentApp} />}
{checkVisibleNav(currentApp) && <DesktopNav currentApp={currentApp} />}
<DesktopDrawer currentApp={currentApp} />
+3 -3
View File
@@ -9,7 +9,7 @@ import MenuIcon from '@mui/icons-material/Menu';
import MoreVertIcon from '@mui/icons-material/MoreVert';
import SettingsOutlinedIcon from '@mui/icons-material/SettingsOutlined';
import type { NavItemApp } from '~/common/app.nav';
import { checkVisibleNav, NavItemApp } from '~/common/app.nav';
import { AgiSquircleIcon } from '~/common/components/icons/AgiSquircleIcon';
import { Brand } from '~/common/app.config';
import { CloseableMenu } from '~/common/components/CloseableMenu';
@@ -125,10 +125,10 @@ export function PageBar(props: { currentApp?: NavItemApp, isMobile?: boolean, sx
<InvertedBar direction='horizontal' sx={props.sx}>
{/* [Mobile] Drawer button */}
{(!!props.isMobile || props.currentApp?.hideNav) && (
{(!!props.isMobile || !checkVisibleNav(props.currentApp)) && (
<InvertedBarCornerItem>
{(!appDrawerContent || props.currentApp?.hideNav) ? (
{(!appDrawerContent || !checkVisibleNav(props.currentApp)) ? (
<IconButton component={Link} href={ROUTE_INDEX} noLinkStyle>
<ArrowBackIcon />
</IconButton>
@@ -64,3 +64,4 @@ export const useLinkStorageOwnerId = () =>
export const rememberChatLinkItem = useTradeStore.getState().rememberChatLinkItem;
export const forgetChatLinkItem = useTradeStore.getState().forgetChatLinkItem;
export const updateChatLinkDeletionKey = useTradeStore.getState().updateChatLinkDeletionKey;
export const hasNoChatLinkItems = () => !useTradeStore.getState().chatLinkItems.length;