| import { useChatContext } from '@/app/components/base/chat/chat/context' | import { useChatContext } from '@/app/components/base/chat/chat/context' | ||||
| import Button from '@/app/components/base/button' | import Button from '@/app/components/base/button' | ||||
| import cn from '@/utils/classnames' | import cn from '@/utils/classnames' | ||||
| import { isValidUrl } from './utils' | |||||
| const MarkdownButton = ({ node }: any) => { | const MarkdownButton = ({ node }: any) => { | ||||
| const { onSend } = useChatContext() | const { onSend } = useChatContext() | ||||
| const variant = node.properties.dataVariant | const variant = node.properties.dataVariant | ||||
| const link = node.properties.dataLink | const link = node.properties.dataLink | ||||
| const size = node.properties.dataSize | const size = node.properties.dataSize | ||||
| function is_valid_url(url: string): boolean { | |||||
| try { | |||||
| const parsed_url = new URL(url) | |||||
| return ['http:', 'https:'].includes(parsed_url.protocol) | |||||
| } | |||||
| catch { | |||||
| return false | |||||
| } | |||||
| } | |||||
| return <Button | return <Button | ||||
| variant={variant} | variant={variant} | ||||
| size={size} | size={size} | ||||
| className={cn('!h-auto min-h-8 select-none whitespace-normal !px-3')} | className={cn('!h-auto min-h-8 select-none whitespace-normal !px-3')} | ||||
| onClick={() => { | onClick={() => { | ||||
| if (is_valid_url(link)) { | |||||
| if (isValidUrl(link)) { | |||||
| window.open(link, '_blank') | window.open(link, '_blank') | ||||
| return | return | ||||
| } | } | ||||
| if(!message) | |||||
| return | |||||
| onSend?.(message) | onSend?.(message) | ||||
| }} | }} | ||||
| > | > |
| */ | */ | ||||
| import React from 'react' | import React from 'react' | ||||
| import { useChatContext } from '@/app/components/base/chat/chat/context' | import { useChatContext } from '@/app/components/base/chat/chat/context' | ||||
| import { isValidUrl } from './utils' | |||||
| const Link = ({ node, children, ...props }: any) => { | const Link = ({ node, children, ...props }: any) => { | ||||
| const { onSend } = useChatContext() | const { onSend } = useChatContext() | ||||
| return <abbr className="cursor-pointer underline !decoration-primary-700 decoration-dashed" onClick={() => onSend?.(hidden_text)} title={node.children[0]?.value || ''}>{node.children[0]?.value || ''}</abbr> | return <abbr className="cursor-pointer underline !decoration-primary-700 decoration-dashed" onClick={() => onSend?.(hidden_text)} title={node.children[0]?.value || ''}>{node.children[0]?.value || ''}</abbr> | ||||
| } | } | ||||
| else { | else { | ||||
| return <a {...props} target="_blank" className="cursor-pointer underline !decoration-primary-700 decoration-dashed">{children || 'Download'}</a> | |||||
| const href = props.href || node.properties?.href | |||||
| if(!isValidUrl(href)) | |||||
| return <span>{children}</span> | |||||
| return <a href={href} target="_blank" className="cursor-pointer underline !decoration-primary-700 decoration-dashed">{children || 'Download'}</a> | |||||
| } | } | ||||
| } | } | ||||
| export const isValidUrl = (url: string): boolean => { | |||||
| return ['http:', 'https:', '//', 'mailto:'].some(prefix => url.startsWith(prefix)) | |||||
| } |