listpage-next 0.0.89 → 0.0.91

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -3,18 +3,22 @@ import { useState } from "react";
3
3
  import { Button, Divider, Input } from "antd";
4
4
  import { ChatInputBottom, ChatInputContent, ChatInputPanel } from "./styles.js";
5
5
  import { ArrowUpOutlined, PauseCircleTwoTone } from "@ant-design/icons";
6
- import { useMessageContext } from "../../context/index.js";
6
+ import { useChatClientContext, useMessageContext } from "../../context/index.js";
7
7
  const ChatSender = (props)=>{
8
8
  const { placeholder, extra, style, className } = props;
9
9
  const { isRequesting, sendMessage } = useMessageContext();
10
10
  const [inputValue, setInputValue] = useState("");
11
+ const { bubbleListRef } = useChatClientContext();
11
12
  const handleClick = async ()=>{
12
13
  if (isRequesting) return;
13
14
  sendMessage({
14
15
  role: 'user',
15
16
  content: inputValue.trim()
17
+ }, ()=>{
18
+ bubbleListRef.current?.scrollToBottom('instant');
16
19
  });
17
20
  setInputValue("");
21
+ bubbleListRef.current?.scrollToBottom('instant');
18
22
  };
19
23
  const handleKeyDown = (e)=>{
20
24
  if ('Enter' === e.key && !e.shiftKey) {
@@ -1,9 +1,9 @@
1
1
  import { CSSProperties } from "react";
2
- export interface ContentProps {
2
+ export interface BubbleListProps {
3
3
  styles?: {
4
4
  topPlaceholder?: CSSProperties;
5
5
  bottomPlaceholder?: CSSProperties;
6
6
  content?: CSSProperties;
7
7
  };
8
8
  }
9
- export declare const Content: (props: ContentProps) => import("react/jsx-runtime").JSX.Element;
9
+ export declare const BubbleList: (props: BubbleListProps) => import("react/jsx-runtime").JSX.Element;
@@ -1,11 +1,32 @@
1
1
  import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { useImperativeHandle, useRef } from "react";
2
3
  import { styled } from "styled-components";
3
4
  import { useChatClientContext, useMessageContext } from "../../context/index.js";
4
- const Content = (props)=>{
5
+ const BubbleList = (props)=>{
5
6
  const { styles } = props;
6
- const { render } = useChatClientContext();
7
+ const containerRef = useRef(null);
8
+ const { render, bubbleListRef } = useChatClientContext();
7
9
  const { messages } = useMessageContext();
10
+ const scrollToBottom = (behavior = "smooth")=>{
11
+ containerRef.current?.scrollTo({
12
+ top: containerRef.current.scrollHeight,
13
+ behavior
14
+ });
15
+ };
16
+ const scrollToBottomWhenAtBottom = (behavior = "instant")=>{
17
+ const ele = containerRef.current;
18
+ if (ele) {
19
+ if (Math.abs(ele.scrollHeight - ele.scrollTop - ele.clientHeight) < 10) scrollToBottom(behavior);
20
+ }
21
+ };
22
+ useImperativeHandle(bubbleListRef, ()=>({
23
+ scrollToBottom,
24
+ scrollToBottomWhenAtBottom
25
+ }), [
26
+ scrollToBottom
27
+ ]);
8
28
  return /*#__PURE__*/ jsxs(ContentContainer, {
29
+ ref: containerRef,
9
30
  children: [
10
31
  /*#__PURE__*/ jsx("div", {
11
32
  style: styles?.topPlaceholder ?? {
@@ -33,4 +54,4 @@ const ContentContainer = styled.div`
33
54
  overflow: auto;
34
55
  position: relative;
35
56
  `;
36
- export { Content };
57
+ export { BubbleList };
@@ -1,11 +1,11 @@
1
1
  import { FooterProps } from "./Footer";
2
2
  import { HeaderProps } from "./Header";
3
- import { ContentProps } from "./Content";
3
+ import { BubbleListProps } from "./BubbleList";
4
4
  export interface ClientContentProps {
5
5
  className?: string;
6
6
  style?: React.CSSProperties;
7
7
  headerProps?: HeaderProps;
8
8
  footerProps?: FooterProps;
9
- contentProps?: ContentProps;
9
+ bubbleProps?: BubbleListProps;
10
10
  }
11
11
  export declare const ClientContent: (props: ClientContentProps) => import("react/jsx-runtime").JSX.Element;
@@ -2,12 +2,13 @@ import { jsx, jsxs } from "react/jsx-runtime";
2
2
  import { useRequest } from "ahooks";
3
3
  import { Footer } from "./Footer.js";
4
4
  import { Header } from "./Header.js";
5
- import { Content } from "./Content.js";
5
+ import { BubbleList } from "./BubbleList.js";
6
6
  import { MessageProvider, useChatClientContext } from "../../context/index.js";
7
7
  import { PageLoading } from "../../../../components/Page/components/Loading/index.js";
8
8
  import { Container } from "./styles.js";
9
+ import { useEffect } from "react";
9
10
  const ClientContentComponent = (props)=>{
10
- const { style, className, headerProps, footerProps, contentProps } = props;
11
+ const { style, className, headerProps, footerProps, bubbleProps } = props;
11
12
  return /*#__PURE__*/ jsxs(Container, {
12
13
  style: style,
13
14
  className: className,
@@ -15,8 +16,8 @@ const ClientContentComponent = (props)=>{
15
16
  /*#__PURE__*/ jsx(Header, {
16
17
  ...headerProps
17
18
  }),
18
- /*#__PURE__*/ jsx(Content, {
19
- ...contentProps
19
+ /*#__PURE__*/ jsx(BubbleList, {
20
+ ...bubbleProps
20
21
  }),
21
22
  /*#__PURE__*/ jsx(Footer, {
22
23
  ...footerProps
@@ -25,8 +26,15 @@ const ClientContentComponent = (props)=>{
25
26
  });
26
27
  };
27
28
  const ClientContent = (props)=>{
28
- const { request } = useChatClientContext();
29
+ const { request, bubbleListRef } = useChatClientContext();
29
30
  const { loading, data } = useRequest(request.getMessages);
31
+ useEffect(()=>{
32
+ if (false === loading) setTimeout(()=>{
33
+ bubbleListRef.current?.scrollToBottom();
34
+ }, 200);
35
+ }, [
36
+ loading
37
+ ]);
30
38
  if (loading) return /*#__PURE__*/ jsx(Container, {
31
39
  style: props.style,
32
40
  className: props.className,
@@ -8,5 +8,6 @@ const Layout = styled_components.div`
8
8
  `;
9
9
  const Content = styled_components.div`
10
10
  flex: 1;
11
+ min-width: 0;
11
12
  `;
12
13
  export { Content, Layout };
@@ -1,6 +1,7 @@
1
1
  import { ReactNode } from "react";
2
2
  import { InfiniteListProps, InfiniteListRef, RenderActions } from "../../../components/InfiniteList";
3
3
  import { BaseMessageInfo, Message, SendMessageRequest } from "./message";
4
+ import { BubbleListRef } from "./useBubbleListRef";
4
5
  export type ChatRequest<SessionData = any, MessageInfo extends BaseMessageInfo = any> = {
5
6
  getConversations: InfiniteListProps<SessionData>['request'];
6
7
  getMessages: () => Promise<MessageInfo[]>;
@@ -17,6 +18,7 @@ export interface ChatClientContextProps<SessionData = any, MessageInfo extends B
17
18
  showUpdateTitleModal: (title: string, onSubmit?: (title: string) => any) => void;
18
19
  conversationListRef: InfiniteListRef<SessionData>;
19
20
  conversationAction: Partial<RenderActions<SessionData>>;
21
+ bubbleListRef: BubbleListRef;
20
22
  }
21
23
  export interface ChatClientProviderProps<SessionData = any, MessageInfo extends BaseMessageInfo = any> {
22
24
  children: ReactNode;
@@ -2,12 +2,14 @@ import { jsxs } from "react/jsx-runtime";
2
2
  import { createContext, useContext, useState } from "react";
3
3
  import { useUpdateTitleModal } from "./useUpdateTitleModal.js";
4
4
  import { useConversationListRef } from "./useConversationListRef.js";
5
+ import { useBubbleListRef } from "./useBubbleListRef.js";
5
6
  const ChatClientContext = /*#__PURE__*/ createContext({});
6
7
  const ChatClientProvider = (props)=>{
7
8
  const { children, request, render } = props;
8
9
  const { updateTitleModalEle, showUpdateTitleModal } = useUpdateTitleModal();
9
10
  const [collapsed, setCollapsed] = useState(false);
10
11
  const { conversationListRef, ...conversationActions } = useConversationListRef();
12
+ const { bubbleListRef } = useBubbleListRef();
11
13
  return /*#__PURE__*/ jsxs(ChatClientContext.Provider, {
12
14
  value: {
13
15
  render,
@@ -16,6 +18,7 @@ const ChatClientProvider = (props)=>{
16
18
  setCollapsed,
17
19
  showUpdateTitleModal,
18
20
  conversationListRef,
21
+ bubbleListRef,
19
22
  conversationAction: conversationActions
20
23
  },
21
24
  children: [
@@ -14,7 +14,7 @@ export type Message<MessageInfo extends BaseMessageInfo = any> = {
14
14
  };
15
15
  export type MessageContextValue<MessageInfo extends BaseMessageInfo = any> = {
16
16
  messages: Message<MessageInfo>[];
17
- sendMessage: (info: MessageInfo) => void;
17
+ sendMessage: (info: MessageInfo, callback?: (info: MessageInfo) => void) => void;
18
18
  isRequesting: boolean;
19
19
  };
20
20
  export type SendMessageRequest<MessageInfo extends BaseMessageInfo = any> = (info: MessageInfo, callbacks: {
@@ -67,7 +67,7 @@ const MessageProvider = ({ initialMessages, children, request })=>{
67
67
  message.id = info.id;
68
68
  }
69
69
  }, []);
70
- const sendMessage = useCallback((info)=>{
70
+ const sendMessage = useCallback((info, onUpdate)=>{
71
71
  setIsRequesting(true);
72
72
  createUserMessage(info);
73
73
  setMessages([
@@ -89,6 +89,7 @@ const MessageProvider = ({ initialMessages, children, request })=>{
89
89
  setMessages([
90
90
  ...messagesRef.current
91
91
  ]);
92
+ onUpdate?.(info);
92
93
  },
93
94
  onSuccess: (id, info)=>{
94
95
  completeAssistantMessage(id, info);
@@ -0,0 +1,11 @@
1
+ import { RefObject } from "react";
2
+ export type BubbleListAction = {
3
+ scrollToBottom: (behavior?: ScrollBehavior) => void;
4
+ scrollToBottomWhenAtBottom: (behavior?: ScrollBehavior) => void;
5
+ };
6
+ export type BubbleListRef = RefObject<BubbleListAction>;
7
+ export declare function useBubbleListRef(): {
8
+ scrollToBottom: (behavior?: ScrollBehavior) => void;
9
+ scrollToBottomWhenAtBottom: (behavior?: ScrollBehavior) => void;
10
+ bubbleListRef: RefObject<BubbleListAction>;
11
+ };
@@ -0,0 +1,12 @@
1
+ import { useRef } from "react";
2
+ function useBubbleListRef() {
3
+ const bubbleListRef = useRef({
4
+ scrollToBottom: ()=>{},
5
+ scrollToBottomWhenAtBottom: ()=>{}
6
+ });
7
+ return {
8
+ bubbleListRef,
9
+ ...bubbleListRef.current
10
+ };
11
+ }
12
+ export { useBubbleListRef };
@@ -1,6 +1,7 @@
1
1
  export declare function useChatContext(): {
2
2
  messages: import("./message").Message<any>[];
3
- sendMessage: (info: any) => void;
3
+ sendMessage: (info: any, callback?: ((info: any) => void) | undefined) => void;
4
4
  deleteConversation: ((key: string) => void) | undefined;
5
5
  updateConversation: ((key: string, item: any) => void) | undefined;
6
+ scrollToBottom: () => void;
6
7
  };
@@ -1,14 +1,15 @@
1
1
  import { useChatClientContext } from "./client.js";
2
2
  import { useMessageContext } from "./message.js";
3
3
  function useChatContext() {
4
- const { conversationAction } = useChatClientContext();
4
+ const { conversationAction, bubbleListRef } = useChatClientContext();
5
5
  const { messages, sendMessage } = useMessageContext();
6
6
  const { deleteItem, updateItem } = conversationAction ?? {};
7
7
  return {
8
8
  messages,
9
9
  sendMessage,
10
10
  deleteConversation: deleteItem,
11
- updateConversation: updateItem
11
+ updateConversation: updateItem,
12
+ scrollToBottom: ()=>bubbleListRef.current?.scrollToBottom()
12
13
  };
13
14
  }
14
15
  export { useChatContext };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "listpage-next",
3
- "version": "0.0.89",
3
+ "version": "0.0.91",
4
4
  "description": "A React component library for creating filter forms with Ant Design",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",