init
This commit is contained in:
319
src/components/chat-view/chat-input/MentionableBadge.tsx
Normal file
319
src/components/chat-view/chat-input/MentionableBadge.tsx
Normal file
@@ -0,0 +1,319 @@
|
||||
import { X } from 'lucide-react'
|
||||
import { PropsWithChildren } from 'react'
|
||||
|
||||
import {
|
||||
Mentionable,
|
||||
MentionableBlock,
|
||||
MentionableCurrentFile,
|
||||
MentionableFile,
|
||||
MentionableFolder,
|
||||
MentionableImage,
|
||||
MentionableUrl,
|
||||
MentionableVault,
|
||||
} from '../../../types/mentionable'
|
||||
|
||||
import { getMentionableIcon } from './utils/get-metionable-icon'
|
||||
|
||||
function BadgeBase({
|
||||
children,
|
||||
onDelete,
|
||||
onClick,
|
||||
isFocused,
|
||||
}: PropsWithChildren<{
|
||||
onDelete: () => void
|
||||
onClick: () => void
|
||||
isFocused: boolean
|
||||
}>) {
|
||||
return (
|
||||
<div
|
||||
className={`infio-chat-user-input-file-badge ${isFocused ? 'infio-chat-user-input-file-badge-focused' : ''}`}
|
||||
onClick={onClick}
|
||||
>
|
||||
{children}
|
||||
<div
|
||||
className="infio-chat-user-input-file-badge-delete"
|
||||
onClick={(evt) => {
|
||||
evt.stopPropagation()
|
||||
onDelete()
|
||||
}}
|
||||
>
|
||||
<X size={10} />
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
function FileBadge({
|
||||
mentionable,
|
||||
onDelete,
|
||||
onClick,
|
||||
isFocused,
|
||||
}: {
|
||||
mentionable: MentionableFile
|
||||
onDelete: () => void
|
||||
onClick: () => void
|
||||
isFocused: boolean
|
||||
}) {
|
||||
const Icon = getMentionableIcon(mentionable)
|
||||
return (
|
||||
<BadgeBase onDelete={onDelete} onClick={onClick} isFocused={isFocused}>
|
||||
<div className="infio-chat-user-input-file-badge-name">
|
||||
{Icon && (
|
||||
<Icon
|
||||
size={10}
|
||||
className="infio-chat-user-input-file-badge-name-icon"
|
||||
/>
|
||||
)}
|
||||
<span>{mentionable.file.name}</span>
|
||||
</div>
|
||||
</BadgeBase>
|
||||
)
|
||||
}
|
||||
|
||||
function FolderBadge({
|
||||
mentionable,
|
||||
onDelete,
|
||||
onClick,
|
||||
isFocused,
|
||||
}: {
|
||||
mentionable: MentionableFolder
|
||||
onDelete: () => void
|
||||
onClick: () => void
|
||||
isFocused: boolean
|
||||
}) {
|
||||
const Icon = getMentionableIcon(mentionable)
|
||||
return (
|
||||
<BadgeBase onDelete={onDelete} onClick={onClick} isFocused={isFocused}>
|
||||
<div className="infio-chat-user-input-file-badge-name">
|
||||
{Icon && (
|
||||
<Icon
|
||||
size={10}
|
||||
className="infio-chat-user-input-file-badge-name-icon"
|
||||
/>
|
||||
)}
|
||||
<span>{mentionable.folder.name}</span>
|
||||
</div>
|
||||
</BadgeBase>
|
||||
)
|
||||
}
|
||||
|
||||
function VaultBadge({
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
mentionable,
|
||||
onDelete,
|
||||
onClick,
|
||||
isFocused,
|
||||
}: {
|
||||
mentionable: MentionableVault
|
||||
onDelete: () => void
|
||||
onClick: () => void
|
||||
isFocused: boolean
|
||||
}) {
|
||||
const Icon = getMentionableIcon(mentionable)
|
||||
return (
|
||||
<BadgeBase onDelete={onDelete} onClick={onClick} isFocused={isFocused}>
|
||||
{/* TODO: Update style */}
|
||||
<div className="infio-chat-user-input-file-badge-name">
|
||||
{Icon && (
|
||||
<Icon
|
||||
size={10}
|
||||
className="infio-chat-user-input-file-badge-name-icon"
|
||||
/>
|
||||
)}
|
||||
<span>Vault</span>
|
||||
</div>
|
||||
</BadgeBase>
|
||||
)
|
||||
}
|
||||
|
||||
function CurrentFileBadge({
|
||||
mentionable,
|
||||
onDelete,
|
||||
onClick,
|
||||
isFocused,
|
||||
}: {
|
||||
mentionable: MentionableCurrentFile
|
||||
onDelete: () => void
|
||||
onClick: () => void
|
||||
isFocused: boolean
|
||||
}) {
|
||||
const Icon = getMentionableIcon(mentionable)
|
||||
return mentionable.file ? (
|
||||
<BadgeBase onDelete={onDelete} onClick={onClick} isFocused={isFocused}>
|
||||
<div className="infio-chat-user-input-file-badge-name">
|
||||
{Icon && (
|
||||
<Icon
|
||||
size={10}
|
||||
className="infio-chat-user-input-file-badge-name-icon"
|
||||
/>
|
||||
)}
|
||||
<span>{mentionable.file.name}</span>
|
||||
</div>
|
||||
<div className="infio-chat-user-input-file-badge-name-block-suffix">
|
||||
{' (Current File)'}
|
||||
</div>
|
||||
</BadgeBase>
|
||||
) : null
|
||||
}
|
||||
|
||||
function BlockBadge({
|
||||
mentionable,
|
||||
onDelete,
|
||||
onClick,
|
||||
isFocused,
|
||||
}: {
|
||||
mentionable: MentionableBlock
|
||||
onDelete: () => void
|
||||
onClick: () => void
|
||||
isFocused: boolean
|
||||
}) {
|
||||
const Icon = getMentionableIcon(mentionable)
|
||||
return (
|
||||
<BadgeBase onDelete={onDelete} onClick={onClick} isFocused={isFocused}>
|
||||
<div className="infio-chat-user-input-file-badge-name-block-name">
|
||||
{Icon && (
|
||||
<Icon
|
||||
size={10}
|
||||
className="infio-chat-user-input-file-badge-name-block-name-icon"
|
||||
/>
|
||||
)}
|
||||
<span>{mentionable.file.name}</span>
|
||||
</div>
|
||||
<div className="infio-chat-user-input-file-badge-name-block-suffix">
|
||||
{` (${mentionable.startLine}:${mentionable.endLine})`}
|
||||
</div>
|
||||
</BadgeBase>
|
||||
)
|
||||
}
|
||||
|
||||
function UrlBadge({
|
||||
mentionable,
|
||||
onDelete,
|
||||
onClick,
|
||||
isFocused,
|
||||
}: {
|
||||
mentionable: MentionableUrl
|
||||
onDelete: () => void
|
||||
onClick: () => void
|
||||
isFocused: boolean
|
||||
}) {
|
||||
const Icon = getMentionableIcon(mentionable)
|
||||
return (
|
||||
<BadgeBase onDelete={onDelete} onClick={onClick} isFocused={isFocused}>
|
||||
<div className="infio-chat-user-input-file-badge-name">
|
||||
{Icon && (
|
||||
<Icon
|
||||
size={10}
|
||||
className="infio-chat-user-input-file-badge-name-icon"
|
||||
/>
|
||||
)}
|
||||
<span>{mentionable.url}</span>
|
||||
</div>
|
||||
</BadgeBase>
|
||||
)
|
||||
}
|
||||
|
||||
function ImageBadge({
|
||||
mentionable,
|
||||
onDelete,
|
||||
onClick,
|
||||
isFocused,
|
||||
}: {
|
||||
mentionable: MentionableImage
|
||||
onDelete: () => void
|
||||
onClick: () => void
|
||||
isFocused: boolean
|
||||
}) {
|
||||
const Icon = getMentionableIcon(mentionable)
|
||||
return (
|
||||
<BadgeBase onDelete={onDelete} onClick={onClick} isFocused={isFocused}>
|
||||
<div className="infio-chat-user-input-file-badge-name">
|
||||
{Icon && (
|
||||
<Icon
|
||||
size={10}
|
||||
className="infio-chat-user-input-file-badge-name-icon"
|
||||
/>
|
||||
)}
|
||||
<span>{mentionable.name}</span>
|
||||
</div>
|
||||
</BadgeBase>
|
||||
)
|
||||
}
|
||||
|
||||
export default function MentionableBadge({
|
||||
mentionable,
|
||||
onDelete,
|
||||
onClick,
|
||||
isFocused = false,
|
||||
}: {
|
||||
mentionable: Mentionable
|
||||
onDelete: () => void
|
||||
onClick: () => void
|
||||
isFocused?: boolean
|
||||
}) {
|
||||
switch (mentionable.type) {
|
||||
case 'file':
|
||||
return (
|
||||
<FileBadge
|
||||
mentionable={mentionable}
|
||||
onDelete={onDelete}
|
||||
onClick={onClick}
|
||||
isFocused={isFocused}
|
||||
/>
|
||||
)
|
||||
case 'folder':
|
||||
return (
|
||||
<FolderBadge
|
||||
mentionable={mentionable}
|
||||
onDelete={onDelete}
|
||||
onClick={onClick}
|
||||
isFocused={isFocused}
|
||||
/>
|
||||
)
|
||||
case 'vault':
|
||||
return (
|
||||
<VaultBadge
|
||||
mentionable={mentionable}
|
||||
onDelete={onDelete}
|
||||
onClick={onClick}
|
||||
isFocused={isFocused}
|
||||
/>
|
||||
)
|
||||
case 'current-file':
|
||||
return (
|
||||
<CurrentFileBadge
|
||||
mentionable={mentionable}
|
||||
onDelete={onDelete}
|
||||
onClick={onClick}
|
||||
isFocused={isFocused}
|
||||
/>
|
||||
)
|
||||
case 'block':
|
||||
return (
|
||||
<BlockBadge
|
||||
mentionable={mentionable}
|
||||
onDelete={onDelete}
|
||||
onClick={onClick}
|
||||
isFocused={isFocused}
|
||||
/>
|
||||
)
|
||||
case 'url':
|
||||
return (
|
||||
<UrlBadge
|
||||
mentionable={mentionable}
|
||||
onDelete={onDelete}
|
||||
onClick={onClick}
|
||||
isFocused={isFocused}
|
||||
/>
|
||||
)
|
||||
case 'image':
|
||||
return (
|
||||
<ImageBadge
|
||||
mentionable={mentionable}
|
||||
onDelete={onDelete}
|
||||
onClick={onClick}
|
||||
isFocused={isFocused}
|
||||
/>
|
||||
)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user