Skip to content

Commit

Permalink
Web Links: per-link options
Browse files Browse the repository at this point in the history
  • Loading branch information
enricoros committed Jan 15, 2025
1 parent 849eb58 commit 20a85a5
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 20 deletions.
4 changes: 2 additions & 2 deletions src/apps/chat/components/composer/Composer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -596,8 +596,8 @@ export function Composer(props: {
.catch((error: any) => addSnackbar({ key: 'attach-file-open-fail', message: `Unable to attach the file "${file.name}" (${error?.message || error?.toString() || 'unknown error'})`, type: 'issue' }));
}, [attachAppendFile]);

const handleAttachWebLinks = React.useCallback(async (urls: string[]) => {
urls.forEach(url => void attachAppendUrl('input-link', url));
const handleAttachWebLinks = React.useCallback(async (links: { url: string }[]) => {
links.forEach(link => void attachAppendUrl('input-link', link.url));
}, [attachAppendUrl]);

const { openWebInputDialog, webInputDialogComponent } = useWebInputModal(handleAttachWebLinks);
Expand Down
39 changes: 21 additions & 18 deletions src/apps/chat/components/composer/WebInputModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,23 +17,27 @@ import { asValidURL } from '~/common/util/urlUtils';
// configuration
const MAX_URLS = 5;

type WebInputData = {
url: string,
// attachImages?: boolean,
}

type WebInputModalInputs = {
urls: { value: string }[];
links: WebInputData[];
}


function WebInputModal(props: {
onClose: () => void,
onWebLinks: (urls: string[]) => void,
onWebLinks: (urls: WebInputData[]) => void,
}) {

// state
const { control: formControl, handleSubmit: formHandleSubmit, formState: { isValid: formIsValid, isDirty: formIsDirty } } = useForm<WebInputModalInputs>({
values: { urls: [{ value: '' }] },
values: { links: [{ url: '' }] },
// mode: 'onChange', // validate on change
});
const { fields: formFields, append: formFieldsAppend, remove: formFieldsRemove } = useFieldArray({ control: formControl, name: 'urls' });
const { fields: formFields, append: formFieldsAppend, remove: formFieldsRemove } = useFieldArray({ control: formControl, name: 'links' });

// derived
const urlFieldCount = formFields.length;
Expand All @@ -45,19 +49,18 @@ function WebInputModal(props: {

const handleClose = React.useCallback(() => onClose(), [onClose]);

const handleSubmit = React.useCallback(({ urls }: WebInputModalInputs) => {
const handleSubmit = React.useCallback(({ links }: WebInputModalInputs) => {
// clean and prefix URLs
const cleanUrls = urls.reduce((acc, { value }) => {
const trimmed = (value || '').trim();
if (!trimmed) return acc;

// this form uses a 'relaxed' URL validation, meaning one can write 'big-agi.com' and we'll assume https://
const relaxedUrl = asValidURL(trimmed, true);
if (relaxedUrl)
acc.push(relaxedUrl);

const cleanUrls = links.reduce((acc, { url, ...linkRest }) => {
const trimmed = (url || '').trim();
if (trimmed) {
// this form uses a 'relaxed' URL validation, meaning one can write 'big-agi.com' and we'll assume https://
const relaxedUrl = asValidURL(trimmed, true);
if (relaxedUrl)
acc.push({ url: relaxedUrl, ...linkRest });
}
return acc;
}, [] as string[]);
}, [] as WebInputData[]);
if (!cleanUrls.length) {
addSnackbar({ key: 'invalid-urls', message: 'Please enter at least one valid web address', type: 'issue', overrides: { autoHideDuration: 2000 } });
return;
Expand Down Expand Up @@ -92,7 +95,7 @@ function WebInputModal(props: {
<Controller
key={field.id}
control={formControl}
name={`urls.${index}.value`}
name={`links.${index}.url`}
rules={{ required: 'Please enter a valid URL' }}
render={({ field: { value, onChange }, fieldState: { error } }) => (
<FormControl error={!!error}>
Expand Down Expand Up @@ -131,7 +134,7 @@ function WebInputModal(props: {
color='neutral'
variant='soft'
disabled={urlFieldCount >= MAX_URLS}
onClick={() => formFieldsAppend({ value: '' })}
onClick={() => formFieldsAppend({ url: '' })}
startDecorator={<AddIcon />}
>
Another
Expand All @@ -155,7 +158,7 @@ function WebInputModal(props: {
}


export function useWebInputModal(onAttachWebLinks: (urls: string[]) => void) {
export function useWebInputModal(onAttachWebLinks: (urls: WebInputData[]) => void) {

// state
const [open, setOpen] = React.useState(false);
Expand Down

0 comments on commit 20a85a5

Please sign in to comment.