@@ -15,59 +15,70 @@ import Dialog from "./Dialog";
1515import Input from "./Input" ;
1616import { GPT_MODEL_NAMES , GPT_4 } from "../utils/constants" ;
1717import Accordion from "./Accordion" ;
18- import type { ModelSettings } from "../utils/types" ;
18+ import type { ModelSettings , SettingModel } from "../utils/types" ;
1919import { useGuestMode } from "../hooks/useGuestMode" ;
20- import { DEFAULT_SETTINGS } from "../hooks/useSettings " ;
20+ import clsx from "clsx " ;
2121
2222export const SettingsDialog : React . FC < {
2323 show : boolean ;
2424 close : ( ) => void ;
25- customSettings : [ ModelSettings , ( settings : ModelSettings ) => void ] ;
26- } > = ( { show, close, customSettings : [ customSettings , setCustomSettings ] } ) => {
25+ customSettings : SettingModel ;
26+ } > = ( { show, close, customSettings } ) => {
2727 const [ settings , setSettings ] = React . useState < ModelSettings > ( {
28- ...customSettings ,
28+ ...customSettings . settings ,
2929 } ) ;
3030 const { isGuestMode } = useGuestMode ( settings . customGuestKey ) ;
3131 const { t } = useTranslation ( [ "settings" , "common" ] ) ;
3232
3333 useEffect ( ( ) => {
34- setSettings ( customSettings ) ;
34+ setSettings ( customSettings . settings ) ;
3535 } , [ customSettings , close ] ) ;
3636
3737 const updateSettings = < Key extends keyof ModelSettings > (
3838 key : Key ,
3939 value : ModelSettings [ Key ]
4040 ) => {
4141 setSettings ( ( prev ) => {
42- if ( key === "customApiKey" && ! value ) {
43- const {
44- customTemperature,
45- customMaxLoops,
46- customEndPoint,
47- customMaxTokens,
48- } = DEFAULT_SETTINGS ;
49- return {
50- ...prev ,
51- [ key ] : value ,
52- customTemperature,
53- customMaxLoops,
54- customEndPoint,
55- customMaxTokens,
56- } ;
57- }
5842 return { ...prev , [ key ] : value } ;
5943 } ) ;
6044 } ;
6145
46+ function urlIsValid ( url : string | undefined ) {
47+ if ( url ) {
48+ const pattern = / ^ ( h t t p s ? : \/ \/ ) ? [ \w . - ] + \. [ a - z A - Z ] { 2 , } ( \/ \S * ) ? $ / ;
49+ return pattern . test ( url ) ;
50+ }
51+ return true ;
52+ }
53+
6254 const handleSave = ( ) => {
63- setCustomSettings ( settings ) ;
55+ if ( ! urlIsValid ( settings . customEndPoint ) ) {
56+ alert (
57+ t (
58+ "Endpoint URL is invalid. Please ensure that you have set a correct URL."
59+ )
60+ ) ;
61+ return ;
62+ }
63+
64+ if ( ! settings . customApiKey ) {
65+ customSettings . resetSettings ( ) ;
66+ } else {
67+ customSettings . saveSettings ( settings ) ;
68+ }
6469 close ( ) ;
6570 return ;
6671 } ;
6772
73+ const handleReset = ( ) => {
74+ customSettings . resetSettings ( ) ;
75+ updateSettings ( "customApiKey" , "" ) ;
76+ close ( ) ;
77+ } ;
78+
6879 const disabled = ! settings . customApiKey ;
6980 const advancedSettings = (
70- < >
81+ < div className = "flex flex-col gap-2" >
7182 < Input
7283 left = {
7384 < >
@@ -79,7 +90,6 @@ export const SettingsDialog: React.FC<{
7990 value = { settings . customEndPoint }
8091 onChange = { ( e ) => updateSettings ( "customEndPoint" , e . target . value ) }
8192 />
82- < br />
8393 < Input
8494 left = {
8595 < >
@@ -102,7 +112,6 @@ export const SettingsDialog: React.FC<{
102112 step : 0.01 ,
103113 } }
104114 />
105- < br />
106115 < Input
107116 left = {
108117 < >
@@ -126,7 +135,6 @@ export const SettingsDialog: React.FC<{
126135 step : 1 ,
127136 } }
128137 />
129- < br />
130138 < Input
131139 left = {
132140 < >
@@ -150,24 +158,31 @@ export const SettingsDialog: React.FC<{
150158 step : 100 ,
151159 } }
152160 />
153- </ >
161+ </ div >
154162 ) ;
155163
156164 return (
157165 < Dialog
158166 header = { `${ t ( "settings" ) } ⚙` }
159167 isShown = { show }
160168 close = { close }
161- footerButton = { < Button onClick = { handleSave } > { t ( "common:save" ) } </ Button > }
169+ footerButton = {
170+ < >
171+ < Button className = "bg-red-400 hover:bg-red-500" onClick = { handleReset } >
172+ { t ( "common:reset" ) }
173+ </ Button >
174+ < Button onClick = { handleSave } > { t ( "common:save" ) } </ Button >
175+ </ >
176+ }
177+ contentClassName = "text-md relative flex flex-col gap-2 p-2 leading-relaxed"
162178 >
163179 < p > { t ( "usage" ) } </ p >
164- < br />
165180 < p
166- className = {
167- settings . customModelName === GPT_4
168- ? "rounded-md border-[2px] border-white/10 bg-yellow-300 text-black"
169- : " "
170- }
181+ className = { clsx (
182+ "my-2" ,
183+ settings . customModelName === GPT_4 &&
184+ "rounded-md border-[2px] border-white/10 bg-yellow-300 text-black "
185+ ) }
171186 >
172187 < FaExclamationCircle className = "inline-block" />
173188
@@ -185,67 +200,60 @@ export const SettingsDialog: React.FC<{
185200 </ b >
186201 </ Trans >
187202 </ p >
188- < br />
189- < div className = "text-md relative flex-auto p-2 leading-relaxed" >
190- < Input
191- left = {
192- < >
193- < FaKey />
194- < span className = "ml-2" > { t ( "key" ) } </ span >
195- </ >
196- }
197- placeholder = { "sk-..." }
198- value = { settings . customApiKey }
199- onChange = { ( e ) => updateSettings ( "customApiKey" , e . target . value ) }
200- />
201- < br className = "md:inline" />
203+ < Input
204+ left = {
205+ < >
206+ < FaKey />
207+ < span className = "ml-2" > { t ( "key" ) } </ span >
208+ </ >
209+ }
210+ placeholder = { "sk-..." }
211+ value = { settings . customApiKey }
212+ onChange = { ( e ) => updateSettings ( "customApiKey" , e . target . value ) }
213+ />
214+ < Input
215+ left = {
216+ < >
217+ < FaMicrochip />
218+ < span className = "ml-2" > { t ( "model" ) } </ span >
219+ </ >
220+ }
221+ type = "combobox"
222+ value = { settings . customModelName }
223+ onChange = { ( ) => null }
224+ setValue = { ( e ) => updateSettings ( "customModelName" , e ) }
225+ attributes = { { options : GPT_MODEL_NAMES } }
226+ disabled = { disabled }
227+ />
228+ { isGuestMode && (
202229 < Input
203230 left = {
204231 < >
205- < FaMicrochip />
206- < span className = "ml-2" > { t ( "model " ) } </ span >
232+ < FaCode />
233+ < span className = "ml-2" > { t ( "guest-key " ) } </ span >
207234 </ >
208235 }
209- type = "combobox"
210- value = { settings . customModelName }
211- onChange = { ( ) => null }
212- setValue = { ( e ) => updateSettings ( "customModelName" , e ) }
213- attributes = { { options : GPT_MODEL_NAMES } }
214- disabled = { disabled }
236+ value = { settings . customGuestKey }
237+ onChange = { ( e ) => updateSettings ( "customGuestKey" , e . target . value ) }
215238 />
216- < br className = "md:inline" />
217- { isGuestMode && (
218- < Input
219- left = {
220- < >
221- < FaCode />
222- < span className = "ml-2" > { t ( "guest-key" ) } </ span >
223- </ >
224- }
225- value = { settings . customGuestKey }
226- onChange = { ( e ) => updateSettings ( "customGuestKey" , e . target . value ) }
227- />
228- ) }
229- < br className = "hidden md:inline" />
230- < Accordion
231- child = { advancedSettings }
232- name = { t ( "advanced-settings" ) }
233- > </ Accordion >
234- < br />
235- < Trans i18nKey = "api-key-notice" ns = "settings" >
236- < strong className = "mt-10" >
237- NOTE: To get a key, sign up for an OpenAI account and visit the
238- following
239- < a
240- href = "https://platform.openai.com/account/api-keys"
241- className = "text-blue-500"
242- >
243- link.
244- </ a >
245- This key is only used in the current browser session
246- </ strong >
247- </ Trans >
248- </ div >
239+ ) }
240+ < Accordion
241+ child = { advancedSettings }
242+ name = { t ( "advanced-settings" ) }
243+ > </ Accordion >
244+ < Trans i18nKey = "api-key-notice" ns = "settings" >
245+ < strong className = "mt-10" >
246+ NOTE: To get a key, sign up for an OpenAI account and visit the
247+ following
248+ < a
249+ href = "https://platform.openai.com/account/api-keys"
250+ className = "text-blue-500"
251+ >
252+ link.
253+ </ a >
254+ This key is only used in the current browser session
255+ </ strong >
256+ </ Trans >
249257 </ Dialog >
250258 ) ;
251259} ;
0 commit comments