diff --git a/src/apps/chat/components/message/ChatMessage.tsx b/src/apps/chat/components/message/ChatMessage.tsx
index 45ad5d794..41880e3b2 100644
--- a/src/apps/chat/components/message/ChatMessage.tsx
+++ b/src/apps/chat/components/message/ChatMessage.tsx
@@ -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.
diff --git a/src/common/app.nav.ts b/src/common/app.nav.ts
index add12385c..35cca0ba7 100644
--- a/src/common/app.nav.ts
+++ b/src/common/app.nav.ts
@@ -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);
\ No newline at end of file
+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;
+}
\ No newline at end of file
diff --git a/src/common/layout/optima/DesktopDrawer.tsx b/src/common/layout/optima/DesktopDrawer.tsx
index c1c9482e5..0d43b194d 100644
--- a/src/common/layout/optima/DesktopDrawer.tsx
+++ b/src/common/layout/optima/DesktopDrawer.tsx
@@ -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();
diff --git a/src/common/layout/optima/DesktopNav.tsx b/src/common/layout/optima/DesktopNav.tsx
index 436422dde..5e9b34758 100644
--- a/src/common/layout/optima/DesktopNav.tsx
+++ b/src/common/layout/optima/DesktopNav.tsx
@@ -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 (
-
- Router.push(item.route)}
- className={`${navItemClasses.typeApp} ${isActive ? navItemClasses.active : ''} ${isPaneOpen ? navItemClasses.paneOpen : ''}`}
- >
- {/*{(isActive && item.iconActive) ? : }*/}
-
-
-
- );
- })
- // (disabled) add this code after the map to add a divider
- .toSpliced(-2, 0, );
+ 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 ;
+
+ return (
+
+ Router.push(app.landingRoute || app.route)}
+ className={`${navItemClasses.typeApp} ${isActive ? navItemClasses.active : ''} ${isPaneOpen ? navItemClasses.paneOpen : ''}`}
+ >
+ {/*{(isActive && app.iconActive) ? : }*/}
+
+
+
+ );
+ });
}, [props.currentApp, isDrawerOpen, toggleDrawer]);
diff --git a/src/common/layout/optima/MobileNavListItem.tsx b/src/common/layout/optima/MobileNavListItem.tsx
index 96c03ae0f..b0bac5b6c 100644
--- a/src/common/layout/optima/MobileNavListItem.tsx
+++ b/src/common/layout/optima/MobileNavListItem.tsx
@@ -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 =>
- ,
- )}
+ {navItems.apps
+ .filter(app => checkVisibileIcon(app))
+ .map((app, appIdx) => {
+ const isActive = app === props.currentApp;
+
+ if (checkDivider(app))
+ return null;
+ // return ;
+
+ return (
+
+
+
+ );
+ })}
{/* Group 2: Social Links */}
diff --git a/src/common/layout/optima/OptimaLayout.tsx b/src/common/layout/optima/OptimaLayout.tsx
index d745c6954..10a67d978 100644
--- a/src/common/layout/optima/OptimaLayout.tsx
+++ b/src/common/layout/optima/OptimaLayout.tsx
@@ -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
- {!currentApp?.hideNav && }
+ {checkVisibleNav(currentApp) && }
diff --git a/src/common/layout/optima/PageBar.tsx b/src/common/layout/optima/PageBar.tsx
index c47a93422..6de96e61b 100644
--- a/src/common/layout/optima/PageBar.tsx
+++ b/src/common/layout/optima/PageBar.tsx
@@ -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
{/* [Mobile] Drawer button */}
- {(!!props.isMobile || props.currentApp?.hideNav) && (
+ {(!!props.isMobile || !checkVisibleNav(props.currentApp)) && (
- {(!appDrawerContent || props.currentApp?.hideNav) ? (
+ {(!appDrawerContent || !checkVisibleNav(props.currentApp)) ? (
diff --git a/src/modules/trade/chatlink/store-chatlink.ts b/src/modules/trade/chatlink/store-chatlink.ts
index d8d0324fe..1c4246312 100644
--- a/src/modules/trade/chatlink/store-chatlink.ts
+++ b/src/modules/trade/chatlink/store-chatlink.ts
@@ -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;