Build/Refactor: lint pre-commit hook and reformat repo to spec (#314)

* build/refactor: move lint/prettier packages to project root, install husky, add pre-commit hook

* refactor: reformat files

* build: put full eslintrc back with all rules
This commit is contained in:
Dan Orlando 2023-05-18 11:09:31 -07:00 committed by GitHub
parent 8d75b25104
commit 7fdc862042
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
157 changed files with 4836 additions and 2403 deletions

View file

@ -1,16 +1,16 @@
import React from 'react';
import { Settings2 } from 'lucide-react';
export default function AdjustButton({ onClick }) {
const clickHandler = e => {
const clickHandler = (e) => {
e.preventDefault();
onClick();
};
return (
<button
onClick={clickHandler}
className="group absolute bottom-11 right-0 flex h-[100%] w-[50px] items-center justify-center bg-transparent p-1 text-gray-500 lg:bottom-0 lg:-right-11"
className="group absolute bottom-11 right-0 flex h-[100%] w-[50px] items-center justify-center bg-transparent p-1 text-gray-500 lg:-right-11 lg:bottom-0"
>
<div className="m-1 mr-0 rounded-md p-2 pt-[10px] pb-[10px] group-hover:bg-gray-100 group-disabled:hover:bg-transparent dark:group-hover:bg-gray-900 dark:group-hover:text-gray-400 dark:group-disabled:hover:bg-transparent">
<div className="m-1 mr-0 rounded-md p-2 pb-[10px] pt-[10px] group-hover:bg-gray-100 group-disabled:hover:bg-transparent dark:group-hover:bg-gray-900 dark:group-hover:text-gray-400 dark:group-disabled:hover:bg-transparent">
<Settings2 size="1em" />
</div>
</button>

View file

@ -31,7 +31,7 @@ function BingAIOptions({ show }) {
setSaveAsDialogShow(true);
};
const setOption = param => newValue => {
const setOption = param => (newValue) => {
let update = {};
update[param] = newValue;
setConversation(prevState => ({
@ -44,7 +44,10 @@ function BingAIOptions({ show }) {
'transition-colors shadow-md rounded-md min-w-[75px] font-normal bg-white border-black/10 hover:border-black/10 focus:border-black/10 dark:border-black/10 dark:hover:border-black/10 dark:focus:border-black/10 border dark:bg-gray-700 text-black dark:text-white';
const defaultClasses =
'p-2 rounded-md min-w-[75px] font-normal bg-white/[.60] dark:bg-gray-700 text-black text-xs';
const defaultSelected = cn(defaultClasses, 'font-medium data-[state=active]:text-white text-xs text-white');
const defaultSelected = cn(
defaultClasses,
'font-medium data-[state=active]:text-white text-xs text-white'
);
const selectedClass = val => val + '-tab ' + defaultSelected;
return (

View file

@ -17,7 +17,7 @@ function ChatGPTOptions() {
const models = endpointsConfig?.['chatGPTBrowser']?.['availableModels'] || [];
const setOption = param => newValue => {
const setOption = param => (newValue) => {
let update = {};
update[param] = newValue;
setConversation(prevState => ({

View file

@ -2,17 +2,17 @@ import React from 'react';
export default function Footer() {
return (
<div className="hidden px-3 pt-2 pb-1 text-center text-xs text-black/50 dark:text-white/50 md:block md:px-4 md:pt-3 md:pb-4">
<div className="hidden px-3 pb-1 pt-2 text-center text-xs text-black/50 dark:text-white/50 md:block md:px-4 md:pb-4 md:pt-3">
<a
href="https://github.com/danny-avila/chatgpt-clone"
target="_blank"
rel="noreferrer"
className="underline"
>
{import.meta.env.VITE_APP_TITLE || "ChatGPT Clone"}
{import.meta.env.VITE_APP_TITLE || 'ChatGPT Clone'}
</a>
. Serves and searches all conversations reliably. All AI convos under one house. Pay per call and not
per month (cents compared to dollars).
. Serves and searches all conversations reliably. All AI convos under one house. Pay per call
and not per month (cents compared to dollars).
</div>
);
}

View file

@ -40,7 +40,7 @@ function GoogleOptions() {
setSaveAsDialogShow(true);
};
const setOption = param => newValue => {
const setOption = param => (newValue) => {
let update = {};
update[param] = newValue;
setConversation(prevState => ({

View file

@ -12,8 +12,8 @@ const alternateName = {
azureOpenAI: 'Azure OpenAI',
bingAI: 'Bing',
chatGPTBrowser: 'ChatGPT',
google: 'PaLM',
}
google: 'PaLM'
};
export default function ModelItem({ endpoint, value, onSelect }) {
const [setTokenDialogOpen, setSetTokenDialogOpen] = useState(false);
@ -42,7 +42,7 @@ export default function ModelItem({ endpoint, value, onSelect }) {
{isUserProvided ? (
<button
className="invisible m-0 mr-1 flex-initial rounded-md p-0 text-xs font-medium text-gray-400 hover:text-gray-700 group-hover:visible dark:font-normal dark:text-gray-400 dark:hover:text-gray-200"
onClick={e => {
onClick={(e) => {
e.preventDefault();
setSetTokenDialogOpen(true);
}}

View file

@ -5,12 +5,7 @@ export default function EndpointItems({ endpoints, onSelect }) {
return (
<>
{endpoints.map(endpoint => (
<EndpointItem
key={endpoint}
value={endpoint}
onSelect={onSelect}
endpoint={endpoint}
/>
<EndpointItem key={endpoint} value={endpoint} onSelect={onSelect} endpoint={endpoint} />
))}
</>
);

View file

@ -2,16 +2,23 @@ import { useState } from 'react';
import { FileUp } from 'lucide-react';
import { cn } from '~/utils/';
const FileUpload = ({ onFileSelected, successText = null, invalidText = null, validator = null, text = null, id = '1' }) => {
const FileUpload = ({
onFileSelected,
successText = null,
invalidText = null,
validator = null,
text = null,
id = '1'
}) => {
const [statusColor, setStatusColor] = useState('text-gray-600');
const [status, setStatus] = useState(null);
const handleFileChange = event => {
const handleFileChange = (event) => {
const file = event.target.files[0];
if (!file) return;
const reader = new FileReader();
reader.onload = e => {
reader.onload = (e) => {
const jsonData = JSON.parse(e.target.result);
if (validator && !validator(jsonData)) {
setStatus('invalid');
@ -23,7 +30,7 @@ const FileUpload = ({ onFileSelected, successText = null, invalidText = null, va
setStatus('success');
setStatusColor('text-green-500 dark:text-green-500');
}
onFileSelected(jsonData);
};
reader.readAsText(file);
@ -38,7 +45,9 @@ const FileUpload = ({ onFileSelected, successText = null, invalidText = null, va
)}
>
<FileUp className="mr-1 flex w-[22px] items-center stroke-1" />
<span className="flex text-xs ">{!status ? text || 'Import' : (status === 'success' ? successText : invalidText)}</span>
<span className="flex text-xs ">
{!status ? text || 'Import' : status === 'success' ? successText : invalidText}
</span>
<input
id={`file-upload-${id}`}
value=""

View file

@ -4,7 +4,13 @@ import EditIcon from '../../svg/EditIcon.jsx';
import TrashIcon from '../../svg/TrashIcon.jsx';
import getIcon from '~/utils/getIcon';
export default function PresetItem({ preset = {}, value, onSelect, onChangePreset, onDeletePreset }) {
export default function PresetItem({
preset = {},
value,
onSelect,
onChangePreset,
onDeletePreset
}) {
const { endpoint } = preset;
const icon = getIcon({
@ -53,7 +59,7 @@ export default function PresetItem({ preset = {}, value, onSelect, onChangePrese
<div className="flex w-4 flex-1" />
<button
className="invisible m-0 mr-1 rounded-md p-2 text-gray-400 hover:text-gray-700 group-hover:visible dark:text-gray-400 dark:hover:text-gray-200 "
onClick={e => {
onClick={(e) => {
e.preventDefault();
onChangePreset(preset);
}}
@ -62,7 +68,7 @@ export default function PresetItem({ preset = {}, value, onSelect, onChangePrese
</button>
<button
className="invisible m-0 rounded-md text-gray-400 hover:text-gray-700 group-hover:visible dark:text-gray-400 dark:hover:text-gray-200 "
onClick={e => {
onClick={(e) => {
e.preventDefault();
onDeletePreset(preset);
}}

View file

@ -39,21 +39,21 @@ export default function NewConversationMenu() {
const deletePresetsMutation = useDeletePresetMutation();
const createPresetMutation = useCreatePresetMutation();
const importPreset = jsonData => {
const importPreset = (jsonData) => {
createPresetMutation.mutate(
{ ...jsonData },
{
onSuccess: data => {
onSuccess: (data) => {
setPresets(data);
},
onError: error => {
onError: (error) => {
console.error('Error uploading the preset:', error);
}
}
);
};
const onFileSelected = jsonData => {
const onFileSelected = (jsonData) => {
const jsonPreset = { ...cleanupPreset({ preset: jsonData, endpointsConfig }), presetId: null };
importPreset(jsonPreset);
};
@ -80,7 +80,7 @@ export default function NewConversationMenu() {
}, [conversation]);
// set the current model
const onSelectEndpoint = newEndpoint => {
const onSelectEndpoint = (newEndpoint) => {
setMenuOpen(false);
if (!newEndpoint) return;
@ -90,7 +90,7 @@ export default function NewConversationMenu() {
};
// set the current model
const onSelectPreset = newPreset => {
const onSelectPreset = (newPreset) => {
setMenuOpen(false);
if (!newPreset) return;
else {
@ -98,7 +98,7 @@ export default function NewConversationMenu() {
}
};
const onChangePreset = preset => {
const onChangePreset = (preset) => {
setPresetModelVisible(true);
setPreset(preset);
};
@ -107,7 +107,7 @@ export default function NewConversationMenu() {
deletePresetsMutation.mutate({ arg: {} });
};
const onDeletePreset = preset => {
const onDeletePreset = (preset) => {
deletePresetsMutation.mutate({ arg: preset });
};
@ -121,10 +121,7 @@ export default function NewConversationMenu() {
return (
<Dialog>
<DropdownMenu
open={menuOpen}
onOpenChange={setMenuOpen}
>
<DropdownMenu open={menuOpen} onOpenChange={setMenuOpen}>
<DropdownMenuTrigger asChild>
<Button
variant="outline"
@ -148,22 +145,18 @@ export default function NewConversationMenu() {
className="overflow-y-auto"
>
{availableEndpoints.length ? (
<EndpointItems
endpoints={availableEndpoints}
onSelect={onSelectEndpoint}
/>
<EndpointItems endpoints={availableEndpoints} onSelect={onSelectEndpoint} />
) : (
<DropdownMenuLabel className="dark:text-gray-300">No endpoint available.</DropdownMenuLabel>
<DropdownMenuLabel className="dark:text-gray-300">
No endpoint available.
</DropdownMenuLabel>
)}
</DropdownMenuRadioGroup>
<div className="mt-6 w-full" />
<DropdownMenuLabel className="flex items-center dark:text-gray-300">
<span
className="cursor-pointer"
onClick={() => setShowPresets(prev => !prev)}
>
<span className="cursor-pointer" onClick={() => setShowPresets(prev => !prev)}>
{showPresets ? 'Hide ' : 'Show '} Presets
</span>
<div className="flex-1" />

View file

@ -16,8 +16,15 @@ function OpenAIOptions() {
const [conversation, setConversation] = useRecoilState(store.conversation) || {};
const { endpoint, conversationId } = conversation;
const { model, chatGptLabel, promptPrefix, temperature, top_p, presence_penalty, frequency_penalty } =
conversation;
const {
model,
chatGptLabel,
promptPrefix,
temperature,
top_p,
presence_penalty,
frequency_penalty
} = conversation;
const endpointsConfig = useRecoilValue(store.endpointsConfig);
@ -36,7 +43,7 @@ function OpenAIOptions() {
setSaveAsDialogShow(true);
};
const setOption = param => newValue => {
const setOption = param => (newValue) => {
let update = {};
update[param] = newValue;
setConversation(prevState => ({

View file

@ -8,9 +8,9 @@ export default function RowButton({ onClick, children, text, className }) {
type="button"
>
{children}
<span className="hidden md:block">{text}</span>
<span className="hidden md:block">{text}</span>
{/* <RegenerateIcon />
<span className="hidden md:block">Regenerate response</span> */}
</button>
);
}
}

View file

@ -9,10 +9,7 @@ function InputWithLabel({ value, onChange, label, id }) {
return (
<>
<Label
htmlFor={id}
className="text-left text-sm font-medium"
>
<Label htmlFor={id} className="text-left text-sm font-medium">
{label}
<br />
</Label>

View file

@ -49,8 +49,8 @@ const SetTokenDialog = ({ open, onOpenChange, endpoint }) => {
const helpText = {
bingAI: (
<small className="break-all text-gray-600">
The Bing Access Token is the "_U" cookie from bing.com. Use dev tools or an extension while logged
into the site to view it.
The Bing Access Token is the "_U" cookie from bing.com. Use dev tools or an extension while
logged into the site to view it.
</small>
),
chatGPTBrowser: (
@ -96,8 +96,8 @@ const SetTokenDialog = ({ open, onOpenChange, endpoint }) => {
>
Create a Service Account
</a>
. Make sure to click 'Create and Continue' to give at least the 'Vertex AI User' role. Lastly, create
a JSON key to import here.
. Make sure to click 'Create and Continue' to give at least the 'Vertex AI User' role.
Lastly, create a JSON key to import here.
</small>
)
};
@ -122,10 +122,7 @@ const SetTokenDialog = ({ open, onOpenChange, endpoint }) => {
}
return (
<Dialog
open={open}
onOpenChange={onOpenChange}
>
<Dialog open={open} onOpenChange={onOpenChange}>
<DialogTemplate
title={`Set Token of ${endpoint}`}
main={
@ -137,7 +134,7 @@ const SetTokenDialog = ({ open, onOpenChange, endpoint }) => {
text="Import Service Account JSON Key"
successText="Successfully Imported Service Account JSON Key"
invalidText="Invalid Service Account JSON Key, Did you import the correct file?"
validator={credentials => {
validator={(credentials) => {
if (!credentials) {
return false;
}
@ -168,7 +165,7 @@ const SetTokenDialog = ({ open, onOpenChange, endpoint }) => {
return true;
}}
onFileSelected={data => {
onFileSelected={(data) => {
setToken(JSON.stringify(data));
}}
/>
@ -244,7 +241,9 @@ const SetTokenDialog = ({ open, onOpenChange, endpoint }) => {
/>
</>
)}
<small className="text-red-600">Your token will be sent to the server, but not saved.</small>
<small className="text-red-600">
Your token will be sent to the server, but not saved.
</small>
{helpText?.[endpoint]}
</div>
}

View file

@ -17,7 +17,7 @@ export default function SubmitButton({
const isTokenProvided = endpointsConfig?.[endpoint]?.userProvide ? !!getToken() : true;
const clickHandler = e => {
const clickHandler = (e) => {
e.preventDefault();
submitMessage();
};
@ -101,12 +101,7 @@ export default function SubmitButton({
width="1em"
xmlns="http://www.w3.org/2000/svg"
>
<line
x1="22"
y1="2"
x2="11"
y2="13"
/>
<line x1="22" y1="2" x2="11" y2="13" />
<polygon points="22 2 15 22 11 13 2 9 22 2" />
</svg>
</div>

View file

@ -34,7 +34,7 @@ export default function TextChat({ isSearchView = false }) {
// const bingStylesRef = useRef(null);
const [showBingToneSetting, setShowBingToneSetting] = useState(false);
const isNotAppendable = (latestMessage?.unfinished & !isSubmitting) || latestMessage?.error;
const isNotAppendable = latestMessage?.unfinished & !isSubmitting || latestMessage?.error;
// auto focus to input, when enter a conversation.
useEffect(() => {
@ -64,12 +64,12 @@ export default function TextChat({ isSearchView = false }) {
setText('');
};
const handleStopGenerating = e => {
const handleStopGenerating = (e) => {
e.preventDefault();
stopGenerating();
};
const handleKeyDown = e => {
const handleKeyDown = (e) => {
if (e.key === 'Enter' && isSubmitting) {
return;
}
@ -83,7 +83,7 @@ export default function TextChat({ isSearchView = false }) {
}
};
const handleKeyUp = e => {
const handleKeyUp = (e) => {
if (e.keyCode === 8 && e.target.value.trim() === '') {
setText(e.target.value);
}
@ -105,7 +105,7 @@ export default function TextChat({ isSearchView = false }) {
isComposing.current = false;
};
const changeHandler = e => {
const changeHandler = (e) => {
const { value } = e.target;
setText(value);