forked from XiaoMo/ChatGPT-Next-Web
feat: improve auto scroll ux and edit model title
This commit is contained in:
parent
cbabb9392c
commit
b5ef552c25
@ -14,7 +14,7 @@
|
|||||||
padding: 4px 10px;
|
padding: 4px 10px;
|
||||||
animation: slide-in ease 0.3s;
|
animation: slide-in ease 0.3s;
|
||||||
box-shadow: var(--card-shadow);
|
box-shadow: var(--card-shadow);
|
||||||
transition: all ease 0.3s;
|
transition: width ease 0.3s;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
height: 16px;
|
height: 16px;
|
||||||
width: var(--icon-width);
|
width: var(--icon-width);
|
||||||
|
@ -370,18 +370,27 @@ function ChatAction(props: {
|
|||||||
function useScrollToBottom() {
|
function useScrollToBottom() {
|
||||||
// for auto-scroll
|
// for auto-scroll
|
||||||
const scrollRef = useRef<HTMLDivElement>(null);
|
const scrollRef = useRef<HTMLDivElement>(null);
|
||||||
const [autoScroll, setAutoScroll] = useState(true);
|
const autoScroll = useRef(true);
|
||||||
const scrollToBottom = useCallback(() => {
|
const scrollToBottom = useCallback(() => {
|
||||||
const dom = scrollRef.current;
|
const dom = scrollRef.current;
|
||||||
if (dom) {
|
if (dom) {
|
||||||
requestAnimationFrame(() => dom.scrollTo(0, dom.scrollHeight));
|
requestAnimationFrame(() => dom.scrollTo(0, dom.scrollHeight));
|
||||||
}
|
}
|
||||||
}, []);
|
}, []);
|
||||||
|
const setAutoScroll = (enable: boolean) => {
|
||||||
|
autoScroll.current = enable;
|
||||||
|
};
|
||||||
|
|
||||||
// auto scroll
|
// auto scroll
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
autoScroll && scrollToBottom();
|
const intervalId = setInterval(() => {
|
||||||
});
|
if (autoScroll.current) {
|
||||||
|
scrollToBottom();
|
||||||
|
}
|
||||||
|
}, 100);
|
||||||
|
return () => clearInterval(intervalId);
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, []);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
scrollRef,
|
scrollRef,
|
||||||
@ -532,7 +541,7 @@ export function EditMessageModal(props: { onClose: () => void }) {
|
|||||||
return (
|
return (
|
||||||
<div className="modal-mask">
|
<div className="modal-mask">
|
||||||
<Modal
|
<Modal
|
||||||
title={Locale.UI.Edit}
|
title={Locale.Chat.EditMessage.Title}
|
||||||
onClose={props.onClose}
|
onClose={props.onClose}
|
||||||
actions={[
|
actions={[
|
||||||
<IconButton
|
<IconButton
|
||||||
@ -590,10 +599,7 @@ export function Chat() {
|
|||||||
type RenderMessage = ChatMessage & { preview?: boolean };
|
type RenderMessage = ChatMessage & { preview?: boolean };
|
||||||
|
|
||||||
const chatStore = useChatStore();
|
const chatStore = useChatStore();
|
||||||
const [session, sessionIndex] = useChatStore((state) => [
|
const session = chatStore.currentSession();
|
||||||
state.currentSession(),
|
|
||||||
state.currentSessionIndex,
|
|
||||||
]);
|
|
||||||
const config = useAppConfig();
|
const config = useAppConfig();
|
||||||
const fontSize = config.fontSize;
|
const fontSize = config.fontSize;
|
||||||
|
|
||||||
@ -608,9 +614,14 @@ export function Chat() {
|
|||||||
const isMobileScreen = useMobileScreen();
|
const isMobileScreen = useMobileScreen();
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
|
||||||
|
const lastBodyScroolTop = useRef(0);
|
||||||
const onChatBodyScroll = (e: HTMLElement) => {
|
const onChatBodyScroll = (e: HTMLElement) => {
|
||||||
const isTouchBottom = e.scrollTop + e.clientHeight >= e.scrollHeight - 10;
|
const isTouchBottom = e.scrollTop + e.clientHeight >= e.scrollHeight - 10;
|
||||||
setHitBottom(isTouchBottom);
|
setHitBottom(isTouchBottom);
|
||||||
|
|
||||||
|
// only enable auto scroll when scroll down and touched bottom
|
||||||
|
setAutoScroll(e.scrollTop >= lastBodyScroolTop.current && isTouchBottom);
|
||||||
|
lastBodyScroolTop.current = e.scrollTop;
|
||||||
};
|
};
|
||||||
|
|
||||||
// prompt hints
|
// prompt hints
|
||||||
@ -1036,7 +1047,6 @@ export function Chat() {
|
|||||||
ref={scrollRef}
|
ref={scrollRef}
|
||||||
onScroll={(e) => onChatBodyScroll(e.currentTarget)}
|
onScroll={(e) => onChatBodyScroll(e.currentTarget)}
|
||||||
onMouseDown={() => inputRef.current?.blur()}
|
onMouseDown={() => inputRef.current?.blur()}
|
||||||
onWheel={(e) => setAutoScroll(hitBottom && e.deltaY > 0)}
|
|
||||||
onTouchStart={() => {
|
onTouchStart={() => {
|
||||||
inputRef.current?.blur();
|
inputRef.current?.blur();
|
||||||
setAutoScroll(false);
|
setAutoScroll(false);
|
||||||
@ -1148,7 +1158,7 @@ export function Chat() {
|
|||||||
}}
|
}}
|
||||||
fontSize={fontSize}
|
fontSize={fontSize}
|
||||||
parentRef={scrollRef}
|
parentRef={scrollRef}
|
||||||
defaultShow={i >= messages.length - 10}
|
defaultShow={i >= messages.length - 6}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -1193,7 +1203,6 @@ export function Chat() {
|
|||||||
value={userInput}
|
value={userInput}
|
||||||
onKeyDown={onInputKeyDown}
|
onKeyDown={onInputKeyDown}
|
||||||
onFocus={() => setAutoScroll(true)}
|
onFocus={() => setAutoScroll(true)}
|
||||||
onBlur={() => setAutoScroll(false)}
|
|
||||||
rows={inputRows}
|
rows={inputRows}
|
||||||
autoFocus={autoFocus}
|
autoFocus={autoFocus}
|
||||||
style={{
|
style={{
|
||||||
|
@ -76,7 +76,7 @@ export function ModelConfigList(props: {
|
|||||||
<input
|
<input
|
||||||
type="number"
|
type="number"
|
||||||
min={100}
|
min={100}
|
||||||
max={32000}
|
max={100000}
|
||||||
value={props.modelConfig.max_tokens}
|
value={props.modelConfig.max_tokens}
|
||||||
onChange={(e) =>
|
onChange={(e) =>
|
||||||
props.updateConfig(
|
props.updateConfig(
|
||||||
@ -169,7 +169,7 @@ export function ModelConfigList(props: {
|
|||||||
title={props.modelConfig.historyMessageCount.toString()}
|
title={props.modelConfig.historyMessageCount.toString()}
|
||||||
value={props.modelConfig.historyMessageCount}
|
value={props.modelConfig.historyMessageCount}
|
||||||
min="0"
|
min="0"
|
||||||
max="32"
|
max="64"
|
||||||
step="1"
|
step="1"
|
||||||
onChange={(e) =>
|
onChange={(e) =>
|
||||||
props.updateConfig(
|
props.updateConfig(
|
||||||
|
@ -19,6 +19,7 @@ const cn = {
|
|||||||
Chat: {
|
Chat: {
|
||||||
SubTitle: (count: number) => `共 ${count} 条对话`,
|
SubTitle: (count: number) => `共 ${count} 条对话`,
|
||||||
EditMessage: {
|
EditMessage: {
|
||||||
|
Title: "编辑消息记录",
|
||||||
Topic: {
|
Topic: {
|
||||||
Title: "聊天主题",
|
Title: "聊天主题",
|
||||||
SubTitle: "更改当前聊天主题",
|
SubTitle: "更改当前聊天主题",
|
||||||
@ -274,7 +275,7 @@ const cn = {
|
|||||||
Context: {
|
Context: {
|
||||||
Toast: (x: any) => `包含 ${x} 条预设提示词`,
|
Toast: (x: any) => `包含 ${x} 条预设提示词`,
|
||||||
Edit: "当前对话设置",
|
Edit: "当前对话设置",
|
||||||
Add: "新增预设对话",
|
Add: "新增一条对话",
|
||||||
Clear: "上下文已清除",
|
Clear: "上下文已清除",
|
||||||
Revert: "恢复上下文",
|
Revert: "恢复上下文",
|
||||||
},
|
},
|
||||||
|
@ -21,6 +21,7 @@ const en: LocaleType = {
|
|||||||
Chat: {
|
Chat: {
|
||||||
SubTitle: (count: number) => `${count} messages`,
|
SubTitle: (count: number) => `${count} messages`,
|
||||||
EditMessage: {
|
EditMessage: {
|
||||||
|
Title: "Edit All Messages",
|
||||||
Topic: {
|
Topic: {
|
||||||
Title: "Topic",
|
Title: "Topic",
|
||||||
SubTitle: "Change the current topic",
|
SubTitle: "Change the current topic",
|
||||||
|
@ -81,7 +81,7 @@ export const ModalConfigValidator = {
|
|||||||
return x as ModelType;
|
return x as ModelType;
|
||||||
},
|
},
|
||||||
max_tokens(x: number) {
|
max_tokens(x: number) {
|
||||||
return limitNumber(x, 0, 32000, 2000);
|
return limitNumber(x, 0, 100000, 2000);
|
||||||
},
|
},
|
||||||
presence_penalty(x: number) {
|
presence_penalty(x: number) {
|
||||||
return limitNumber(x, -2, 2, 0);
|
return limitNumber(x, -2, 2, 0);
|
||||||
|
Loading…
Reference in New Issue
Block a user