Explorar o código

feat: optimize conversation operation (#479)

Joel hai 1 ano
pai
achega
838825d747

+ 8 - 10
web/app/components/explore/sidebar/app-nav-item/index.tsx

@@ -56,16 +56,14 @@ export default function AppNavItem({
         <div className='overflow-hidden text-ellipsis whitespace-nowrap'>{name}</div>
       </div>
       {
-        !isSelected && (
-          <div className={cn(s.opBtn, 'shrink-0')} onClick={e => e.stopPropagation()}>
-            <ItemOperation
-              isPinned={isPinned}
-              togglePin={togglePin}
-              isShowDelete={!uninstallable}
-              onDelete={() => onDelete(id)}
-            />
-          </div>
-        )
+        <div className={cn(s.opBtn, 'shrink-0')} onClick={e => e.stopPropagation()}>
+          <ItemOperation
+            isPinned={isPinned}
+            togglePin={togglePin}
+            isShowDelete={!uninstallable && !isSelected}
+            onDelete={() => onDelete(id)}
+          />
+        </div>
       }
     </div>
   )

+ 25 - 4
web/app/components/share/chat/index.tsx

@@ -67,6 +67,8 @@ const Main: FC<IMainProps> = ({
   * conversation info
   */
   const [allConversationList, setAllConversationList] = useState<ConversationItem[]>([])
+  const [isClearConversationList, { setTrue: clearConversationListTrue, setFalse: clearConversationListFalse }] = useBoolean(false)
+  const [isClearPinnedConversationList, { setTrue: clearPinnedConversationListTrue, setFalse: clearPinnedConversationListFalse }] = useBoolean(false)
   const {
     conversationList,
     setConversationList,
@@ -89,18 +91,32 @@ const Main: FC<IMainProps> = ({
   const [hasPinnedMore, setHasPinnedMore] = useState<boolean>(true)
   const onMoreLoaded = ({ data: conversations, has_more }: any) => {
     setHasMore(has_more)
-    setConversationList([...conversationList, ...conversations])
+    if (isClearConversationList) {
+      setConversationList(conversations)
+      clearConversationListFalse()
+    }
+    else {
+      setConversationList([...conversationList, ...conversations])
+    }
   }
   const onPinnedMoreLoaded = ({ data: conversations, has_more }: any) => {
     setHasPinnedMore(has_more)
-    setPinnedConversationList([...pinnedConversationList, ...conversations])
+    if (isClearPinnedConversationList) {
+      setPinnedConversationList(conversations)
+      clearPinnedConversationListFalse()
+    }
+    else {
+      setPinnedConversationList([...pinnedConversationList, ...conversations])
+    }
   }
   const [controlUpdateConversationList, setControlUpdateConversationList] = useState(0)
   const noticeUpdateList = () => {
-    setConversationList([])
     setHasMore(true)
-    setPinnedConversationList([])
+    clearConversationListTrue()
+
     setHasPinnedMore(true)
+    clearPinnedConversationListTrue()
+
     setControlUpdateConversationList(Date.now())
   }
   const handlePin = async (id: string) => {
@@ -126,6 +142,9 @@ const Main: FC<IMainProps> = ({
     await delConversation(isInstalledApp, installedAppInfo?.id, toDeleteConversationId)
     notify({ type: 'success', message: t('common.api.success') })
     hideConfirm()
+    if (currConversationId === toDeleteConversationId)
+      handleConversationIdChange('-1')
+
     noticeUpdateList()
   }
 
@@ -496,7 +515,9 @@ const Main: FC<IMainProps> = ({
     return (
       <Sidebar
         list={conversationList}
+        isClearConversationList={isClearConversationList}
         pinnedList={pinnedConversationList}
+        isClearPinnedConversationList={isClearPinnedConversationList}
         onMoreLoaded={onMoreLoaded}
         onPinnedMoreLoaded={onPinnedMoreLoaded}
         isNoMore={!hasMore}

+ 12 - 5
web/app/components/share/chat/sidebar/index.tsx

@@ -17,7 +17,9 @@ export type ISidebarProps = {
   currentId: string
   onCurrentIdChange: (id: string) => void
   list: ConversationItem[]
+  isClearConversationList: boolean
   pinnedList: ConversationItem[]
+  isClearPinnedConversationList: boolean
   isInstalledApp: boolean
   installedAppId?: string
   siteInfo: SiteInfo
@@ -36,7 +38,9 @@ const Sidebar: FC<ISidebarProps> = ({
   currentId,
   onCurrentIdChange,
   list,
+  isClearConversationList,
   pinnedList,
+  isClearPinnedConversationList,
   isInstalledApp,
   installedAppId,
   siteInfo,
@@ -92,16 +96,17 @@ const Sidebar: FC<ISidebarProps> = ({
           <PencilSquareIcon className="mr-2 h-4 w-4" /> {t('share.chat.newChat')}
         </Button>
       </div>
-      <div className='flex-grow h-0 overflow-y-auto overflow-x-hidden'>
+      <div className={'flex-grow flex flex-col h-0 overflow-y-auto overflow-x-hidden'}>
         {/* pinned list */}
         {hasPinned && (
-          <div className='mt-4 px-4'>
+          <div className={cn('mt-4 px-4', list.length === 0 && 'flex flex-col flex-grow')}>
             <div className='mb-1.5 leading-[18px] text-xs text-gray-500 font-medium uppercase'>{t('share.chat.pinnedTitle')}</div>
             <List
-              className={maxListHeight}
+              className={cn(list.length > 0 ? maxListHeight : 'flex-grow')}
               currentId={currentId}
               onCurrentIdChange={onCurrentIdChange}
               list={pinnedList}
+              isClearConversationList={isClearPinnedConversationList}
               isInstalledApp={isInstalledApp}
               installedAppId={installedAppId}
               onMoreLoaded={onPinnedMoreLoaded}
@@ -114,8 +119,8 @@ const Sidebar: FC<ISidebarProps> = ({
           </div>
         )}
         {/* unpinned list */}
-        <div className='mt-4 px-4'>
-          {hasPinned && (
+        <div className={cn('mt-4 px-4', !hasPinned && 'flex flex-col flex-grow')}>
+          {(hasPinned && list.length > 0) && (
             <div className='mb-1.5 leading-[18px] text-xs text-gray-500 font-medium uppercase'>{t('share.chat.unpinnedTitle')}</div>
           )}
           <List
@@ -123,6 +128,7 @@ const Sidebar: FC<ISidebarProps> = ({
             currentId={currentId}
             onCurrentIdChange={onCurrentIdChange}
             list={list}
+            isClearConversationList={isClearConversationList}
             isInstalledApp={isInstalledApp}
             installedAppId={installedAppId}
             onMoreLoaded={onMoreLoaded}
@@ -133,6 +139,7 @@ const Sidebar: FC<ISidebarProps> = ({
             onDelete={onDelete}
           />
         </div>
+
       </div>
       <div className="flex flex-shrink-0 pr-4 pb-4 pl-4">
         <div className="text-gray-400 font-normal text-xs">© {copyRight} {(new Date()).getFullYear()}</div>

+ 14 - 14
web/app/components/share/chat/sidebar/list/index.tsx

@@ -17,6 +17,7 @@ export type IListProps = {
   currentId: string
   onCurrentIdChange: (id: string) => void
   list: ConversationItem[]
+  isClearConversationList: boolean
   isInstalledApp: boolean
   installedAppId?: string
   onMoreLoaded: (res: { data: ConversationItem[]; has_more: boolean }) => void
@@ -32,6 +33,7 @@ const List: FC<IListProps> = ({
   currentId,
   onCurrentIdChange,
   list,
+  isClearConversationList,
   isInstalledApp,
   installedAppId,
   onMoreLoaded,
@@ -46,7 +48,7 @@ const List: FC<IListProps> = ({
   useInfiniteScroll(
     async () => {
       if (!isNoMore) {
-        const lastId = list[list.length - 1]?.id
+        const lastId = !isClearConversationList ? list[list.length - 1]?.id : undefined
         const { data: conversations, has_more }: any = await fetchConversations(isInstalledApp, installedAppId, lastId, isPinned)
         onMoreLoaded({ data: conversations, has_more })
       }
@@ -63,7 +65,7 @@ const List: FC<IListProps> = ({
   return (
     <nav
       ref={listRef}
-      className={cn(className, 'shrink-0 space-y-1 bg-white pb-[60px] overflow-y-auto')}
+      className={cn(className, 'shrink-0 space-y-1 bg-white pb-[85px] overflow-y-auto')}
     >
       {list.map((item) => {
         const isCurrent = item.id === currentId
@@ -93,18 +95,16 @@ const List: FC<IListProps> = ({
               <span>{item.name}</span>
             </div>
 
-            {
-              !isCurrent && (
-                <div className={cn(s.opBtn, 'shrink-0')} onClick={e => e.stopPropagation()}>
-                  <ItemOperation
-                    isPinned={isPinned}
-                    togglePin={() => onPinChanged(item.id)}
-                    isShowDelete
-                    onDelete={() => onDelete(item.id)}
-                  />
-                </div>
-              )
-            }
+            {item.id !== '-1' && (
+              <div className={cn(s.opBtn, 'shrink-0')} onClick={e => e.stopPropagation()}>
+                <ItemOperation
+                  isPinned={isPinned}
+                  togglePin={() => onPinChanged(item.id)}
+                  isShowDelete
+                  onDelete={() => onDelete(item.id)}
+                />
+              </div>
+            )}
           </div>
         )
       })}