2
2
3
3
import { Check , ChevronDown } from 'lucide-react' ;
4
4
import { useTranslations } from 'next-intl' ;
5
- import { useState } from 'react' ;
5
+ import { memo , useCallback , useMemo , useState } from 'react' ;
6
6
7
7
import { GetAppConfig } from '@/actions/configs/get-app-config' ;
8
8
import {
@@ -33,7 +33,7 @@ type ChatTopBarProps = {
33
33
isEmbed ?: boolean ;
34
34
} ;
35
35
36
- const CommandItems = ( { callback, currentModel, models } : CommandItemsProps ) => {
36
+ const CommandItems = memo ( ( { callback, currentModel, models } : CommandItemsProps ) => {
37
37
const { user } = useCurrentUser ( ) ;
38
38
39
39
return models . map ( ( model ) => (
@@ -43,7 +43,6 @@ const CommandItems = ({ callback, currentModel, models }: CommandItemsProps) =>
43
43
value = { model . value }
44
44
onSelect = { ( currentValue ) => {
45
45
const value = currentValue === currentModel ? '' : currentValue ;
46
-
47
46
callback ( { currentModel : value , currentModelLabel : model . label , isOpen : false } ) ;
48
47
} }
49
48
>
@@ -61,9 +60,9 @@ const CommandItems = ({ callback, currentModel, models }: CommandItemsProps) =>
61
60
</ div >
62
61
</ CommandItem >
63
62
) ) ;
64
- } ;
63
+ } ) ;
65
64
66
- export const ChatTopBar = ( { isEmbed = false } : ChatTopBarProps ) => {
65
+ const ChatTopBarComponent = ( { isEmbed = false } : ChatTopBarProps ) => {
67
66
const t = useTranslations ( 'chat.top-bar' ) ;
68
67
69
68
const { chatMessages, conversationId, currentModel, setCurrentModel, setCurrentModelLabel } =
@@ -74,42 +73,51 @@ export const ChatTopBar = ({ isEmbed = false }: ChatTopBarProps) => {
74
73
75
74
const [ open , setOpen ] = useState ( false ) ;
76
75
77
- const [ paidModels , freeModels ] = ( appConfig ?. ai ?. flatMap ( ( ai ) => ai [ 'text-models' ] ) ?? [ ] ) . reduce <
78
- [ Model [ ] , Model [ ] , Model [ ] ]
79
- > (
80
- ( acc , model ) => {
81
- if ( model . isSubscription ) {
82
- acc [ 0 ] . push ( model ) ;
83
- } else {
84
- acc [ 1 ] . push ( model ) ;
85
- }
86
- return acc ;
87
- } ,
88
- [ [ ] , [ ] , [ ] ] ,
76
+ const [ paidModels , freeModels ] = useMemo (
77
+ ( ) =>
78
+ ( appConfig ?. ai ?. flatMap ( ( ai ) => ai [ 'text-models' ] ) ?? [ ] ) . reduce < [ Model [ ] , Model [ ] ] > (
79
+ ( acc , model ) => {
80
+ if ( model . isSubscription ) {
81
+ acc [ 0 ] . push ( model ) ;
82
+ } else {
83
+ acc [ 1 ] . push ( model ) ;
84
+ }
85
+ return acc ;
86
+ } ,
87
+ [ [ ] , [ ] ] ,
88
+ ) ,
89
+ [ appConfig ?. ai ] ,
89
90
) ;
90
91
91
92
const messages = chatMessages [ conversationId ] ?? [ ] ;
92
93
93
- const handleCommandItemsCallback = ( {
94
- currentModel,
95
- currentModelLabel,
96
- isOpen,
97
- } : {
98
- currentModel : string ;
99
- currentModelLabel : string ;
100
- isOpen : boolean ;
101
- } ) => {
102
- setCurrentModel ( currentModel ) ;
103
- setCurrentModelLabel ( currentModelLabel ) ;
104
- setOpen ( isOpen ) ;
105
- } ;
94
+ const handleCommandItemsCallback = useCallback (
95
+ ( {
96
+ currentModel,
97
+ currentModelLabel,
98
+ isOpen,
99
+ } : {
100
+ currentModel : string ;
101
+ currentModelLabel : string ;
102
+ isOpen : boolean ;
103
+ } ) => {
104
+ setCurrentModel ( currentModel ) ;
105
+ setCurrentModelLabel ( currentModelLabel ) ;
106
+ setOpen ( isOpen ) ;
107
+ } ,
108
+ [ setCurrentModel , setCurrentModelLabel ] ,
109
+ ) ;
110
+
111
+ const handleOpenChange = useCallback ( ( value : boolean ) => {
112
+ setOpen ( value ) ;
113
+ } , [ ] ) ;
106
114
107
115
return (
108
116
< div className = { cn ( 'w-full h-[75px]' , ! messages . length && 'h-full' ) } >
109
117
< div className = "flex flex-1 flex-col text-base md:px-5 lg:px-1 xl:px-5 mx-auto gap-3 md:max-w-3xl lg:max-w-[40rem] xl:max-w-4xl pt-4 px-4" >
110
118
< div className = "flex items-center justify-center w-full gap-x-2" >
111
119
{ ! isEmbed && (
112
- < Popover open = { open } onOpenChange = { setOpen } >
120
+ < Popover open = { open } onOpenChange = { handleOpenChange } >
113
121
< PopoverTrigger asChild >
114
122
< Button
115
123
variant = "ghost"
@@ -151,3 +159,8 @@ export const ChatTopBar = ({ isEmbed = false }: ChatTopBarProps) => {
151
159
</ div >
152
160
) ;
153
161
} ;
162
+
163
+ CommandItems . displayName = 'CommandItems' ;
164
+ ChatTopBarComponent . displayName = 'ChatTopBar' ;
165
+
166
+ export const ChatTopBar = memo ( ChatTopBarComponent ) ;
0 commit comments