fix: attachment preview issue

This commit is contained in:
Louis 2024-12-17 16:07:11 +07:00
parent f2db31781e
commit 66e37d80d6
No known key found for this signature in database
GPG Key ID: 44FA9F4D33C37DE2
7 changed files with 61 additions and 63 deletions

View File

@ -1,6 +1,8 @@
import { openFileExplorer, joinPath, baseName } from '@janhq/core' import { openFileExplorer, joinPath, baseName, fs } from '@janhq/core'
import { useAtomValue } from 'jotai' import { useAtomValue } from 'jotai'
import { getFileInfo } from '@/utils/file'
import { janDataFolderPathAtom } from '@/helpers/atoms/AppConfig.atom' import { janDataFolderPathAtom } from '@/helpers/atoms/AppConfig.atom'
import { activeAssistantAtom } from '@/helpers/atoms/Assistant.atom' import { activeAssistantAtom } from '@/helpers/atoms/Assistant.atom'
import { selectedModelAtom } from '@/helpers/atoms/Model.atom' import { selectedModelAtom } from '@/helpers/atoms/Model.atom'
@ -47,13 +49,23 @@ export const usePath = () => {
const onViewFile = async (id: string) => { const onViewFile = async (id: string) => {
if (!activeThread) return if (!activeThread) return
let filePath = undefined
id = await baseName(id) id = await baseName(id)
filePath = await joinPath(['threads', `${activeThread.id}/files`, `${id}`])
if (!filePath) return // New ID System
const fullPath = await joinPath([janDataFolderPath, filePath]) if (!id.startsWith('file-')) {
openFileExplorer(fullPath) const threadFilePath = await joinPath([
janDataFolderPath,
'threads',
`${activeThread.id}/files`,
id,
])
openFileExplorer(threadFilePath)
} else {
id = id.split('.')[0]
const fileName = (await getFileInfo(id)).filename
const filesPath = await joinPath([janDataFolderPath, 'files', fileName])
openFileExplorer(filesPath)
}
} }
const onViewFileContainer = async () => { const onViewFileContainer = async () => {

View File

@ -126,7 +126,7 @@ const ChatInput = () => {
const renderPreview = (fileUpload: any) => { const renderPreview = (fileUpload: any) => {
if (fileUpload) { if (fileUpload) {
if (fileUpload.type === 'image') { if (fileUpload.type === 'image') {
return <ImageUploadPreview file={fileUpload[0].file} /> return <ImageUploadPreview file={fileUpload.file} />
} else { } else {
return <FileUploadPreview /> return <FileUploadPreview />
} }

View File

@ -1,44 +1,39 @@
import { memo } from 'react' import { memo, useEffect, useState } from 'react'
import { Tooltip } from '@janhq/joi'
import { FolderOpenIcon } from 'lucide-react'
import { usePath } from '@/hooks/usePath' import { usePath } from '@/hooks/usePath'
import { toGibibytes } from '@/utils/converter' import { getFileInfo } from '@/utils/file'
import { openFileTitle } from '@/utils/titleUtils'
import Icon from '../FileUploadPreview/Icon' import Icon from '../FileUploadPreview/Icon'
const DocMessage = ({ id, name }: { id: string; name?: string }) => { const DocMessage = ({ id }: { id: string }) => {
const { onViewFile, onViewFileContainer } = usePath() const { onViewFile } = usePath()
const [fileInfo, setFileInfo] = useState<
{ filename: string; id: string } | undefined
>()
useEffect(() => {
if (!fileInfo) {
getFileInfo(id).then((data) => {
setFileInfo(data)
})
}
}, [fileInfo, id])
return ( return (
<div className="group/file bg-secondary relative mb-2 inline-flex w-60 cursor-pointer gap-x-3 overflow-hidden rounded-lg p-4"> <div className="group/file bg-secondary relative mb-2 inline-flex w-60 cursor-pointer gap-x-3 overflow-hidden rounded-lg p-4">
<div <div
className="absolute left-0 top-0 z-20 hidden h-full w-full bg-black/20 backdrop-blur-sm group-hover/file:inline-block" className="absolute left-0 top-0 z-20 hidden h-full w-full bg-black/20 opacity-50 group-hover/file:inline-block"
onClick={() => onViewFile(`${id}.pdf`)} onClick={() => onViewFile(`${id}.pdf`)}
/> />
<Tooltip
trigger={
<div
className="absolute right-2 top-2 z-20 hidden h-8 w-8 cursor-pointer items-center justify-center rounded-md bg-[hsla(var(--app-bg))] group-hover/file:flex"
onClick={onViewFileContainer}
>
<FolderOpenIcon size={20} />
</div>
}
content={<span>{openFileTitle()}</span>}
/>
<Icon type="pdf" /> <Icon type="pdf" />
<div className="w-full"> <div className="w-full">
<h6 className="line-clamp-1 w-4/5 font-medium"> <h6 className="line-clamp-1 w-4/5 overflow-hidden font-medium">
{name?.replaceAll(/[-._]/g, ' ')} {fileInfo?.filename}
</h6> </h6>
{/* <p className="text-[hsla(var(--text-secondary)]"> <p className="text-[hsla(var(--text-secondary)] line-clamp-1 overflow-hidden truncate">
{toGibibytes(Number(size))} {fileInfo?.id ?? id}
</p> */} </p>
</div> </div>
</div> </div>
) )

View File

@ -1,34 +1,11 @@
import { memo } from 'react' import { memo } from 'react'
import { Tooltip } from '@janhq/joi'
import { FolderOpenIcon } from 'lucide-react'
import { usePath } from '@/hooks/usePath'
import { openFileTitle } from '@/utils/titleUtils'
import { RelativeImage } from '../TextMessage/RelativeImage' import { RelativeImage } from '../TextMessage/RelativeImage'
const ImageMessage = ({ image }: { image: string }) => { const ImageMessage = ({ image }: { image: string }) => {
const { onViewFile, onViewFileContainer } = usePath()
return ( return (
<div className="group/image relative mb-2 inline-flex cursor-pointer overflow-hidden rounded-xl"> <div className="group/file relative mb-2 inline-flex overflow-hidden rounded-xl">
<div className="left-0 top-0 z-20 h-full w-full group-hover/image:inline-block"> <RelativeImage src={image} />
<RelativeImage src={image} onClick={() => onViewFile(image)} />
</div>
<Tooltip
trigger={
<div
className="absolute right-2 top-2 z-20 hidden h-8 w-8 cursor-pointer items-center justify-center rounded-md bg-[hsla(var(--app-bg))] group-hover/image:flex"
onClick={onViewFileContainer}
>
<FolderOpenIcon size={20} />
</div>
}
content={<span>{openFileTitle()}</span>}
/>
</div> </div>
) )
} }

View File

@ -7,7 +7,7 @@ export const RelativeImage = ({
onClick, onClick,
}: { }: {
src: string src: string
onClick: () => void onClick?: () => void
}) => { }) => {
const [path, setPath] = useState<string>('') const [path, setPath] = useState<string>('')
@ -17,9 +17,12 @@ export const RelativeImage = ({
}) })
}, []) }, [])
return ( return (
<button onClick={onClick}> <button
onClick={onClick}
className={onClick ? 'cursor-pointer' : 'cursor-default'}
>
<img <img
className="aspect-auto h-[300px] cursor-pointer" className="aspect-auto h-[300px]"
alt={src} alt={src}
src={src.includes('files/') ? `file://${path}/${src}` : src} src={src.includes('files/') ? `file://${path}/${src}` : src}
/> />

View File

@ -125,7 +125,9 @@ const MessageContainer: React.FC<
> >
<> <>
{image && <ImageMessage image={image} />} {image && <ImageMessage image={image} />}
{attachedFile && <DocMessage id={props.id} name={props.id} />} {attachedFile && (
<DocMessage id={props.attachments?.[0]?.file_id ?? props.id} />
)}
{editMessage === props.id ? ( {editMessage === props.id ? (
<div> <div>

View File

@ -47,3 +47,12 @@ export const uploader = () => {
}) })
return uppy return uppy
} }
/**
* Get the file information from the server.
*/
export const getFileInfo = (id: string) => {
return fetch(`${API_BASE_URL}/v1/files/${id}`)
.then((e) => e.json())
.catch(() => undefined)
}