Skip to content

Commit c1377b0

Browse files
committed
🌟feat: support previewing videos and audio #18
1 parent dc509b5 commit c1377b0

File tree

8 files changed

+1399
-29
lines changed

8 files changed

+1399
-29
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "blinko",
3-
"version": "0.0.20",
3+
"version": "0.0.21",
44
"private": true,
55
"browser": {
66
"fs": false,

pnpm-lock.yaml

Lines changed: 1321 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/components/Common/Editor/attachmentsRender.tsx

Lines changed: 52 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -39,50 +39,87 @@ const AttachmentsRender = observer(({ files, preview = false, columns = 3 }: IPr
3939
}
4040
})
4141
}))
42-
const DeleteIcon = observer(({ className, file }: { className: string, file: FileType }) => {
42+
43+
const DeleteIcon = observer(({ className, file, size = 20 }: { className: string, file: FileType, size?: number }) => {
4344
return <>
4445
<TipsPopover isLoading={store.deleteFile.loading.value} content={t('this-operation-will-be-delete-resource-are-you-sure')}
4546
onConfirm={async e => {
4647
store.deleteFile.call(file)
4748
}}>
48-
<Icon className={className}
49-
icon="basil:cross-solid" width="20" height="20" />
49+
<div className={`opacity-70 hover:opacity-100 !bg-foreground cursor-pointer rounded-sm transition-al ${className}`}>
50+
<Icon className='white' icon="basil:cross-solid" width={size} height={size} />
51+
</div>
52+
5053
</TipsPopover >
5154
</>
5255
})
5356

57+
const DownloadIcon = observer(({ className, file, size = 20 }: { className: string, file: FileType, size?: number }) => {
58+
return <div className={`hidden p-1 group-hover:block transition-all absolute z-10 right-[5px] top-[5px] !text-background opacity-70 hover:opacity-100 !bg-foreground cursor-pointer rounded-sm transition-all ${className}`}>
59+
<Icon onClick={() => {
60+
helper.download.downloadByLink(file.uploadPromise.value)
61+
}} icon="tabler:download" width="15" height="15" />
62+
</div>
63+
})
64+
5465
return <>
66+
{/* image render */}
5567
<div className={`columns-${columns} md:columns-${columns}`}>
5668
<PhotoProvider>
57-
{files?.filter(i => i.isImage).map((file, index) => (
69+
{files?.filter(i => i.previewType == 'image').map((file, index) => (
5870
<div className='relative group'>
5971
{file.uploadPromise?.loading?.value && <div className='absolute inset-0 flex items-center justify-center w-full h-full'>
6072
<Icon icon="line-md:uploading-loop" width="40" height="40" />
6173
</div>}
6274

6375
<PhotoView width={150} src={file.preview} >
64-
<Image
65-
src={file.preview}
66-
className='rounded-lg mb-4'
67-
// onLoad={() => { URL.revokeObjectURL(file.preview) }}
68-
/>
76+
<Image src={file.preview} className='rounded-lg mb-4' />
6977
</PhotoView>
7078

7179
{!file.uploadPromise?.loading?.value && !preview &&
72-
<DeleteIcon className='absolute z-10 right-[5px] top-[5px] !text-background opacity-80 hover:opacity-100 bg-foreground cursor-pointer rounded-sm transition-all'
80+
<DeleteIcon className='absolute z-10 right-[5px] top-[5px]'
7381
file={file} />
7482
}
75-
{preview && <Icon onClick={() => {
76-
helper.download.downloadByLink(file.uploadPromise.value)
77-
}} className='hidden er:block transition-all absolute z-10 right-[5px] top-[5px] !text-background opacity-80 hover:opacity-100 bg-foreground cursor-pointer rounded-sm transition-all' icon="tabler:download" width="15" height="15" />
83+
{preview && <DownloadIcon className=''
84+
file={file} />
7885
}
7986
</div>
8087
))}
8188
</PhotoProvider>
89+
</div>
8290

91+
{/* video render */}
92+
<div className={`columns-1 md:columns-1`}>
93+
{files?.filter(i => i.previewType == 'video').map((file, index) => (
94+
<div className='group relative flex p-2 items-center gap-2 cursor-pointer tansition-all rounded-2xl'>
95+
<video src={file.preview} id="player" playsInline controls className='rounded-2xl w-full z-0' />
96+
{!file.uploadPromise?.loading?.value && !preview &&
97+
<DeleteIcon className='absolute z-10 right-[5px] top-[5px]'
98+
file={file} />
99+
}
100+
{preview && <DownloadIcon className='top-[8px] right-[8px]' file={file} />}
101+
</div>
102+
))}
83103
</div>
104+
105+
{/* audio render */}
106+
<div className={`columns-1 md:columns-1`}>
107+
{files?.filter(i => i.previewType == 'audio').map((file, index) => (
108+
<div className='group relative flex p-2 items-center gap-2 cursor-pointer tansition-all rounded-2xl'>
109+
<audio src={file.preview} id="player" playsInline controls className='rounded-2xl w-full' />
110+
{!file.uploadPromise?.loading?.value && !preview &&
111+
<DeleteIcon className='absolute z-10 right-[5px] top-[5px]'
112+
file={file} />
113+
}
114+
{preview && <DownloadIcon className='top-[8px] right-[8px]' file={file} />}
115+
</div>
116+
))}
117+
</div >
118+
119+
120+
{/* other file render */}
84121
<div className={`${helper.env.isIOS ? 'columns-1' : 'columns-' + columns} mt-3 select-none`}>
85-
{files?.filter(i => !i.isImage).map((file, index) => (
122+
{files?.filter(i => i.previewType == 'other').map((file, index) => (
86123
<div onClick={() => {
87124
if (preview) {
88125
helper.download.downloadByLink(file.uploadPromise.value)
@@ -91,8 +128,7 @@ const AttachmentsRender = observer(({ files, preview = false, columns = 3 }: IPr
91128
<FileIcons path={file.name} isLoading={file.uploadPromise?.loading?.value} />
92129
<div className='truncate text-sm font-bold'>{file.name}</div>
93130
{!file.uploadPromise?.loading?.value && !preview &&
94-
<DeleteIcon className='ml-auto w-[35px] !text-foreground hover:bg-background cursor-pointer rounded-sm tansition-all'
95-
file={file} />}
131+
<DeleteIcon className='ml-auto w-[35px]' file={file} />}
96132
</div>
97133
))}
98134
</div >

src/components/Common/Editor/index.tsx

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,11 +41,11 @@ export const HandleFileType = (originFiles: Attachment[]): FileType[] => {
4141
if (originFiles.length == 0) return []
4242
const res = originFiles?.map(file => {
4343
const extension = helper.getFileExtension(file.name)
44+
const previewType = helper.getFileType(file.name)
4445
return {
4546
name: file.name,
4647
size: file.size,
47-
//@ts-ignore
48-
isImage: 'JPEG/JPG/PNG/BMP/TIFF/TIF/WEBP/SVG'.includes(extension?.toUpperCase() ?? null),
48+
previewType,
4949
extension: extension ?? '',
5050
preview: file.path,
5151
uploadPromise: new PromiseState({ function: async () => file.path })
@@ -56,7 +56,6 @@ export const HandleFileType = (originFiles: Attachment[]): FileType[] => {
5656
}
5757

5858

59-
6059
const Editor = observer(({ content, onChange, onSend, isSendLoading, bottomSlot, originFiles }: IProps) => {
6160
const { t } = useTranslation()
6261
const isPc = useMediaQuery('(min-width: 768px)')
@@ -134,11 +133,11 @@ const Editor = observer(({ content, onChange, onSend, isSendLoading, bottomSlot,
134133
uploadFiles(acceptedFiles) {
135134
const _acceptedFiles = acceptedFiles.map(file => {
136135
const extension = helper.getFileExtension(file.name)
136+
const previewType = helper.getFileType(file.name)
137137
return {
138138
name: file.name,
139139
size: file.size,
140-
//@ts-ignore
141-
isImage: 'JPEG/JPG/PNG/BMP/TIFF/TIF/WEBP/SVG'.includes(extension?.toUpperCase() ?? null),
140+
previewType,
142141
extension: extension ?? '',
143142
preview: URL.createObjectURL(file),
144143
uploadPromise: new PromiseState({

src/components/Common/Editor/type.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ export type OnSendContentType = {
3636
export type FileType = {
3737
name: string
3838
size: number
39-
isImage: boolean
39+
previewType: 'image' | 'audio' | 'video' | 'other'
4040
extension: string
4141
preview: any
4242
uploadPromise: PromiseState<any>

src/lib/helper.ts

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { type Tag } from '@/server/types';
22
import { _ } from './lodash';
33
import i18n from './i18n';
4+
import { FileType } from '@/components/Common/Editor/type';
45

56
const valMap = {
67
undefined: '',
@@ -111,9 +112,18 @@ export const helper = {
111112
}
112113
return null
113114
},
114-
isImage(filename: string) {
115-
const extension = helper.getFileExtension(filename) ?? '';
116-
return 'JPEG/JPG/PNG/BMP/TIFF/TIF/WEBP/SVG'.includes(extension?.toUpperCase() ?? null)
115+
getFileType(filename: string): FileType['previewType'] {
116+
const extension = helper.getFileExtension(filename) ?? ''
117+
if ('jpeg/jpg/png/bmp/tiff/tif/webp/svg'.includes(extension?.toLowerCase() ?? null)) {
118+
return 'image'
119+
}
120+
if ('mp4/webm/ogg/mov/wmv'.includes(extension?.toLowerCase() ?? null)) {
121+
return 'video';
122+
}
123+
if ('mp3/aac/wav/ogg'.includes(extension?.toLowerCase() ?? null)) {
124+
return 'audio';
125+
}
126+
return 'other'
117127
},
118128
promise: {
119129
async sleep(ms) {

src/pages/resources.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ const Page = observer(() => {
2929
const extension = helper.getFileExtension(i.path)
3030
return <Card shadow="none" className="group bg-background cursor-pointer px-4 pt-4 mb-4 pb-2 flex flex-col gap-2 items-center">
3131
{
32-
helper.isImage(i.path) ?
32+
helper.getFileType(i.path) == 'image' ?
3333
<PhotoView width={150} src={i.path} >
3434
<Image radius="sm" className="w-full" src={i.path} alt='' />
3535
</PhotoView> :

src/styles/editor.css

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1+
12
.ͼo {
23
background-color: transparent !important;
34
}
5+
46
.ͼ1x {
57
background-color: var(--background);
68
color: var(--foreground);
@@ -37,6 +39,10 @@
3739
color: #3B82F6 !important;
3840
}
3941

42+
.mdxeditor-toolbar .white {
43+
color: white !important;
44+
}
45+
4046
.mdxeditor-toolbar .primary-foreground {
4147
color: var(--primary-foreground) !important;
4248
}

0 commit comments

Comments
 (0)