@@ -6,6 +6,7 @@ import React, {
6
6
useMemo ,
7
7
useCallback ,
8
8
Fragment ,
9
+ RefObject ,
9
10
} from "react" ;
10
11
11
12
import SendWhiteIcon from "../icons/send-white.svg" ;
@@ -382,11 +383,13 @@ function ChatAction(props: {
382
383
) ;
383
384
}
384
385
385
- function useScrollToBottom ( ) {
386
+ function useScrollToBottom (
387
+ scrollRef : RefObject < HTMLDivElement > ,
388
+ detach : boolean = false ,
389
+ ) {
386
390
// for auto-scroll
387
- const scrollRef = useRef < HTMLDivElement > ( null ) ;
388
- const [ autoScroll , setAutoScroll ] = useState ( true ) ;
389
391
392
+ const [ autoScroll , setAutoScroll ] = useState ( true ) ;
390
393
function scrollDomToBottom ( ) {
391
394
const dom = scrollRef . current ;
392
395
if ( dom ) {
@@ -399,7 +402,7 @@ function useScrollToBottom() {
399
402
400
403
// auto scroll
401
404
useEffect ( ( ) => {
402
- if ( autoScroll ) {
405
+ if ( autoScroll && ! detach ) {
403
406
scrollDomToBottom ( ) ;
404
407
}
405
408
} ) ;
@@ -658,7 +661,17 @@ function _Chat() {
658
661
const [ userInput , setUserInput ] = useState ( "" ) ;
659
662
const [ isLoading , setIsLoading ] = useState ( false ) ;
660
663
const { submitKey, shouldSubmit } = useSubmitHandler ( ) ;
661
- const { scrollRef, setAutoScroll, scrollDomToBottom } = useScrollToBottom ( ) ;
664
+ const scrollRef = useRef < HTMLDivElement > ( null ) ;
665
+ const isScrolledToBottom = scrollRef ?. current
666
+ ? Math . abs (
667
+ scrollRef . current . scrollHeight -
668
+ ( scrollRef . current . scrollTop + scrollRef . current . clientHeight ) ,
669
+ ) <= 1
670
+ : false ;
671
+ const { setAutoScroll, scrollDomToBottom } = useScrollToBottom (
672
+ scrollRef ,
673
+ isScrolledToBottom ,
674
+ ) ;
662
675
const [ hitBottom , setHitBottom ] = useState ( true ) ;
663
676
const isMobileScreen = useMobileScreen ( ) ;
664
677
const navigate = useNavigate ( ) ;
@@ -1003,7 +1016,6 @@ function _Chat() {
1003
1016
setHitBottom ( isHitBottom ) ;
1004
1017
setAutoScroll ( isHitBottom ) ;
1005
1018
} ;
1006
-
1007
1019
function scrollToBottom ( ) {
1008
1020
setMsgRenderIndex ( renderMessages . length - CHAT_PAGE_SIZE ) ;
1009
1021
scrollDomToBottom ( ) ;
@@ -1088,6 +1100,47 @@ function _Chat() {
1088
1100
} ;
1089
1101
// eslint-disable-next-line react-hooks/exhaustive-deps
1090
1102
} , [ ] ) ;
1103
+
1104
+ const handlePaste = useCallback (
1105
+ async ( event : React . ClipboardEvent < HTMLTextAreaElement > ) => {
1106
+ const currentModel = chatStore . currentSession ( ) . mask . modelConfig . model ;
1107
+ if ( ! isVisionModel ( currentModel ) ) { return ; }
1108
+ const items = ( event . clipboardData || window . clipboardData ) . items ;
1109
+ for ( const item of items ) {
1110
+ if ( item . kind === "file" && item . type . startsWith ( "image/" ) ) {
1111
+ event . preventDefault ( ) ;
1112
+ const file = item . getAsFile ( ) ;
1113
+ if ( file ) {
1114
+ const images : string [ ] = [ ] ;
1115
+ images . push ( ...attachImages ) ;
1116
+ images . push (
1117
+ ...( await new Promise < string [ ] > ( ( res , rej ) => {
1118
+ setUploading ( true ) ;
1119
+ const imagesData : string [ ] = [ ] ;
1120
+ compressImage ( file , 256 * 1024 )
1121
+ . then ( ( dataUrl ) => {
1122
+ imagesData . push ( dataUrl ) ;
1123
+ setUploading ( false ) ;
1124
+ res ( imagesData ) ;
1125
+ } )
1126
+ . catch ( ( e ) => {
1127
+ setUploading ( false ) ;
1128
+ rej ( e ) ;
1129
+ } ) ;
1130
+ } ) ) ,
1131
+ ) ;
1132
+ const imagesLength = images . length ;
1133
+
1134
+ if ( imagesLength > 3 ) {
1135
+ images . splice ( 3 , imagesLength - 3 ) ;
1136
+ }
1137
+ setAttachImages ( images ) ;
1138
+ }
1139
+ }
1140
+ }
1141
+ } ,
1142
+ [ attachImages , chatStore ] ,
1143
+ ) ;
1091
1144
1092
1145
async function uploadImage ( ) {
1093
1146
const images : string [ ] = [ ] ;
@@ -1437,6 +1490,7 @@ function _Chat() {
1437
1490
onKeyDown = { onInputKeyDown }
1438
1491
onFocus = { scrollToBottom }
1439
1492
onClick = { scrollToBottom }
1493
+ onPaste = { handlePaste }
1440
1494
rows = { inputRows }
1441
1495
autoFocus = { autoFocus }
1442
1496
style = { {
0 commit comments