Skip to content

Commit

Permalink
💄 style: fix scroll and expand (lobehub#2470)
Browse files Browse the repository at this point in the history
* 💄 style: Fix scroll and expand

* 💄 style: improve empty card

---------

Co-authored-by: arvinxx <arvinx@foxmail.com>
  • Loading branch information
canisminor1990 and arvinxx authored May 14, 2024
1 parent 5f4523a commit 8b1202a
Show file tree
Hide file tree
Showing 20 changed files with 240 additions and 181 deletions.
17 changes: 17 additions & 0 deletions src/app/(main)/chat/(workspace)/@topic/_layout/Desktop.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { PropsWithChildren } from 'react';
import { Flexbox } from 'react-layout-kit';

import Header from '../features/Header';

const Layout = ({ children }: PropsWithChildren) => {
return (
<>
<Header />
<Flexbox height={'100%'} style={{ overflow: 'hidden', position: 'relative' }} width={'100%'}>
{children}
</Flexbox>
</>
);
};

export default Layout;
21 changes: 21 additions & 0 deletions src/app/(main)/chat/(workspace)/@topic/_layout/Mobile.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { PropsWithChildren } from 'react';
import { Flexbox } from 'react-layout-kit';

import TopicSearchBar from '../features/TopicSearchBar';

const Layout = ({ children }: PropsWithChildren) => {
return (
<Flexbox gap={8} height={'100%'} padding={'8px 8px 0'} style={{ overflow: 'hidden' }}>
<TopicSearchBar />
<Flexbox
height={'100%'}
style={{ marginInline: -8, overflow: 'hidden', position: 'relative' }}
width={'calc(100% + 16px)'}
>
{children}
</Flexbox>
</Flexbox>
);
};

export default Layout;
8 changes: 7 additions & 1 deletion src/app/(main)/chat/(workspace)/@topic/default.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,21 @@
import { isMobileDevice } from '@/utils/responsive';

import Desktop from './_layout/Desktop';
import Mobile from './_layout/Mobile';
import SystemRole from './features/SystemRole';
import TopicListContent from './features/TopicListContent';

const Topic = () => {
const mobile = isMobileDevice();

const Layout = mobile ? Mobile : Desktop;

return (
<>
{!mobile && <SystemRole />}
<TopicListContent mobile={mobile} />
<Layout>
<TopicListContent />
</Layout>
</>
);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ export const Placeholder = memo(() => {
});

export const SkeletonList = memo(() => (
<Flexbox>
<Flexbox style={{ paddingTop: 6 }}>
{Array.from({ length: 8 }).map((_, i) => (
<Placeholder key={i} />
))}
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,12 @@ const useStyles = createStyles(({ css, token, isDarkMode }) => ({
`,
container: css`
cursor: pointer;
width: calc(100% - 16px);
margin-block: 2px;
margin-inline: 8px;
padding: 8px;
border-radius: ${token.borderRadius}px;
&:hover {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,100 @@
'use client';

import { EmptyCard } from '@lobehub/ui';
import { useThemeMode } from 'antd-style';
import isEqual from 'fast-deep-equal';
import React, { memo, useCallback, useRef } from 'react';
import { useTranslation } from 'react-i18next';
import { Flexbox } from 'react-layout-kit';
import { Virtuoso, VirtuosoHandle } from 'react-virtuoso';

import { imageUrl } from '@/const/url';
import { useChatStore } from '@/store/chat';
import { topicSelectors } from '@/store/chat/selectors';
import { useUserStore } from '@/store/user';
import { ChatTopic } from '@/types/topic';

import { Placeholder, SkeletonList } from './SkeletonList';
import TopicItem from './TopicItem';

const TopicListContent = memo(() => {
const { t } = useTranslation('chat');
const virtuosoRef = useRef<VirtuosoHandle>(null);
const { isDarkMode } = useThemeMode();
const [topicsInit, activeTopicId, topicLength] = useChatStore((s) => [
s.topicsInit,
s.activeTopicId,
topicSelectors.currentTopicLength(s),
]);
const [visible, updateGuideState] = useUserStore((s) => [
s.preference.guide?.topic,
s.updateGuideState,
]);

const topics = useChatStore(
(s) => [
{
favorite: false,
id: 'default',
title: t('topic.defaultTitle'),
} as ChatTopic,
...topicSelectors.displayTopics(s),
],
isEqual,
);

const itemContent = useCallback(
(index: number, { id, favorite, title }: ChatTopic) =>
index === 0 ? (
<TopicItem active={!activeTopicId} fav={favorite} title={title} />
) : (
<TopicItem active={activeTopicId === id} fav={favorite} id={id} key={id} title={title} />
),
[activeTopicId],
);

const activeIndex = topics.findIndex((topic) => topic.id === activeTopicId);

import Header from './Header';
import { Topic } from './Topic';
import TopicSearchBar from './TopicSearchBar';

const TopicListContent = ({ mobile }: { mobile?: boolean }) => {
return (
<Flexbox gap={mobile ? 8 : 0} height={'100%'} style={{ overflow: 'hidden' }}>
{mobile ? <TopicSearchBar /> : <Header />}
<Flexbox gap={16} height={'100%'} style={{ paddingTop: 6, position: 'relative' }}>
<Topic mobile={mobile} />
</Flexbox>
</Flexbox>
return !topicsInit ? (
<SkeletonList />
) : (
<>
{topicLength === 0 && visible && (
<Flexbox paddingInline={8}>
<EmptyCard
alt={t('topic.guide.desc')}
cover={imageUrl(`empty_topic_${isDarkMode ? 'dark' : 'light'}.webp`)}
desc={t('topic.guide.desc')}
height={120}
imageProps={{
priority: true,
}}
onVisibleChange={(visible) => {
updateGuideState({ topic: visible });
}}
style={{ flex: 'none', marginBottom: 12 }}
title={t('topic.guide.title')}
visible={visible}
width={200}
/>
</Flexbox>
)}
<Virtuoso
components={{ ScrollSeekPlaceholder: Placeholder }}
computeItemKey={(_, item) => item.id}
data={topics}
fixedItemHeight={44}
initialTopMostItemIndex={Math.max(activeIndex, 0)}
itemContent={itemContent}
overscan={44 * 10}
ref={virtuosoRef}
scrollSeekConfiguration={{
enter: (velocity) => Math.abs(velocity) > 350,
exit: (velocity) => Math.abs(velocity) < 10,
}}
/>
</>
);
};
});

export default TopicListContent;
27 changes: 12 additions & 15 deletions src/app/(main)/chat/(workspace)/_layout/Desktop/TopicPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@

import { DraggablePanel, DraggablePanelContainer } from '@lobehub/ui';
import { createStyles, useResponsive } from 'antd-style';
import { PropsWithChildren, memo, useEffect, useLayoutEffect, useState } from 'react';
import isEqual from 'fast-deep-equal';
import { PropsWithChildren, memo, useEffect, useState } from 'react';

import SafeSpacing from '@/components/SafeSpacing';
import { CHAT_SIDEBAR_WIDTH } from '@/const/layoutTokens';
Expand All @@ -26,35 +27,31 @@ const useStyles = createStyles(({ css, token }) => ({
const TopicPanel = memo(({ children }: PropsWithChildren) => {
const { styles } = useStyles();
const { md = true, lg = true } = useResponsive();
const [showAgentSettings, toggleConfig, isPreferenceInit] = useGlobalStore((s) => [
const [showAgentSettings, toggleConfig] = useGlobalStore((s) => [
s.preference.showChatSideBar,
s.toggleChatSideBar,
s.isPreferenceInit,
]);
const [expand, setExpand] = useState(showAgentSettings);
const [cacheExpand, setCacheExpand] = useState<boolean>(Boolean(showAgentSettings));

const handleExpand = (e: boolean) => {
toggleConfig(e);
setExpand(e);
const handleExpand = (expand: boolean) => {
if (isEqual(expand, Boolean(showAgentSettings))) return;
toggleConfig(expand);
setCacheExpand(expand);
};

useLayoutEffect(() => {
if (!isPreferenceInit) return;
setExpand(showAgentSettings);
}, [isPreferenceInit, showAgentSettings]);

useEffect(() => {
if (lg && showAgentSettings) setExpand(true);
if (!lg) setExpand(false);
}, [lg, showAgentSettings]);
if (lg && cacheExpand) toggleConfig(true);
if (!lg) toggleConfig(false);
}, [lg, cacheExpand]);

return (
<DraggablePanel
className={styles.drawer}
classNames={{
content: styles.content,
}}
expand={expand}
expand={showAgentSettings}
minWidth={CHAT_SIDEBAR_WIDTH}
mode={md ? 'fixed' : 'float'}
onExpandChange={handleExpand}
Expand Down
10 changes: 9 additions & 1 deletion src/app/(main)/chat/(workspace)/_layout/Mobile/TopicModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,15 @@ const Topics = memo(({ children }: PropsWithChildren) => {
const { t } = useTranslation('chat');

return (
<Modal allowFullscreen onCancel={() => setOpen(false)} open={open} title={t('topic.title')}>
<Modal
allowFullscreen
onCancel={() => setOpen(false)}
open={open}
styles={{
body: { padding: 0 },
}}
title={t('topic.title')}
>
{children}
</Modal>
);
Expand Down
Loading

0 comments on commit 8b1202a

Please sign in to comment.