Skip to content

Commit 9698602

Browse files
authored
Merge pull request #125 from hunghg255/update-option-upload-media
2 parents 510fe83 + e5b1e17 commit 9698602

File tree

9 files changed

+126
-38
lines changed

9 files changed

+126
-38
lines changed

docs/extensions/Image/index.md

+17
Original file line numberDiff line numberDiff line change
@@ -34,3 +34,20 @@ const extensions = [
3434

3535
- ImageGif is a node extension that allows you to add an ImageGif to your editor.
3636
- More: [ImageGif](/extensions/ImageGif/index.md)
37+
38+
## Props
39+
40+
```ts
41+
interface IImageOptions extends GeneralOptions<IImageOptions> {
42+
/** Function for uploading files */
43+
upload?: (file: File) => Promise<string>
44+
45+
HTMLAttributes?: any
46+
47+
acceptMimes?: string[]
48+
maxSize?: number
49+
50+
/** The source URL of the image */
51+
resourceImage: 'upload' | 'link' | 'both'
52+
}
53+
```

docs/extensions/Video/index.md

+34
Original file line numberDiff line numberDiff line change
@@ -29,3 +29,37 @@ const extensions = [
2929
}), // [!code ++]
3030
];
3131
```
32+
33+
## Props
34+
35+
```ts
36+
interface VideoOptions extends GeneralOptions<VideoOptions> {
37+
/**
38+
* Indicates whether fullscreen play is allowed
39+
*
40+
* @default true
41+
*/
42+
allowFullscreen: boolean
43+
/**
44+
* Indicates whether to display the frameborder
45+
*
46+
* @default false
47+
*/
48+
frameborder: boolean
49+
/**
50+
* Width of the video, can be a number or string
51+
*
52+
* @default VIDEO_SIZE['size-medium']
53+
*/
54+
width: number | string
55+
/** HTML attributes object for passing additional attributes */
56+
HTMLAttributes: {
57+
[key: string]: any
58+
}
59+
/** Function for uploading files */
60+
upload?: (file: File) => Promise<string>
61+
62+
/** The source URL of the video */
63+
resourceVideo: 'upload' | 'link' | 'both'
64+
}
65+
```

src/extensions/Image/Image.ts

+4
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ export interface SetImageAttrsOptions {
3030
const DEFAULT_OPTIONS: any = {
3131
acceptMimes: ['image/jpeg', 'image/gif', 'image/png', 'image/jpg'],
3232
maxSize: 1024 * 1024 * 5, // 5MB
33+
resourceImage: 'both',
3334
}
3435

3536
declare module '@tiptap/core' {
@@ -59,6 +60,9 @@ export interface IImageOptions extends GeneralOptions<IImageOptions> {
5960

6061
acceptMimes?: string[]
6162
maxSize?: number
63+
64+
/** The source URL of the image */
65+
resourceImage: 'upload' | 'link' | 'both'
6266
}
6367

6468
export const Image = TiptapImage.extend<IImageOptions>({

src/extensions/Image/components/ActionImageButton.tsx

+33-15
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1-
import { useRef, useState } from 'react'
1+
import { useMemo, useRef, useState } from 'react'
22

33
import { ActionButton, Button, Checkbox, Input, Label, Tabs, TabsContent, TabsList, TabsTrigger } from '@/components'
44
import { Dialog, DialogContent, DialogTitle, DialogTrigger } from '@/components/ui/dialog'
55
import { ImageCropper } from '@/extensions/Image/components/ImageCropper'
66
import { useLocale } from '@/locales'
77
import { actionDialogImage, useDialogImage } from '@/extensions/Image/store'
8+
import Image from '@/extensions/Image/Image'
89

910
function ActionImageButton(props: any) {
1011
const { t } = useLocale()
@@ -16,15 +17,20 @@ function ActionImageButton(props: any) {
1617

1718
const [imageInline, setImageInline] = useState(false)
1819

20+
const uploadOptions = useMemo(() => {
21+
const uploadOptions = props.editor.extensionManager.extensions.find(
22+
(extension: any) => extension.name === Image.name,
23+
)?.options
24+
25+
return uploadOptions
26+
}, [props.editor])
27+
1928
async function handleFile(event: any) {
2029
const files = event?.target?.files
2130
if (!props.editor || props.editor.isDestroyed || files.length === 0) {
2231
return
2332
}
2433
const file = files[0]
25-
const uploadOptions = props.editor.extensionManager.extensions.find(
26-
(extension: any) => extension.name === 'image',
27-
)?.options
2834

2935
let src = ''
3036
if (uploadOptions.upload) {
@@ -65,17 +71,29 @@ function ActionImageButton(props: any) {
6571
<DialogContent>
6672
<DialogTitle>{t('editor.image.dialog.title')}</DialogTitle>
6773

68-
<Tabs defaultValue="upload" activationMode="manual">
74+
<Tabs
75+
defaultValue={
76+
uploadOptions.resourceImage === 'both' || uploadOptions.resourceImage === 'upload'
77+
? 'upload'
78+
: 'link'
79+
}
80+
activationMode="manual"
81+
>
6982
<TabsList className="richtext-grid richtext-w-full richtext-grid-cols-2">
70-
<TabsTrigger value="upload">
71-
{t('editor.image.dialog.tab.upload')}
72-
{' '}
73-
</TabsTrigger>
74-
<TabsTrigger value="link">
75-
{' '}
76-
{t('editor.image.dialog.tab.url')}
77-
{' '}
78-
</TabsTrigger>
83+
{uploadOptions.resourceImage === 'both' || uploadOptions.resourceImage === 'upload'
84+
? (
85+
<TabsTrigger value="upload">
86+
{t('editor.image.dialog.tab.upload')}
87+
</TabsTrigger>
88+
)
89+
: <></>}
90+
{uploadOptions.resourceImage === 'both' || uploadOptions.resourceImage === 'link'
91+
? (
92+
<TabsTrigger value="link">
93+
{t('editor.image.dialog.tab.url')}
94+
</TabsTrigger>
95+
)
96+
: <></>}
7997
</TabsList>
8098

8199
<div className="richtext-flex richtext-items-center richtext-gap-[4px] richtext-my-[10px]">
@@ -115,7 +133,7 @@ function ActionImageButton(props: any) {
115133
<div className="richtext-flex richtext-items-center richtext-gap-2">
116134
<Input
117135
type="url"
118-
autoFocus={true}
136+
autoFocus
119137
value={link}
120138
onChange={e => setLink(e.target.value)}
121139
required

src/extensions/Video/Video.ts

+4
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@ export interface VideoOptions extends GeneralOptions<VideoOptions> {
3333
}
3434
/** Function for uploading files */
3535
upload?: (file: File) => Promise<string>
36+
37+
/** The source URL of the video */
38+
resourceVideo: 'upload' | 'link' | 'both'
3639
}
3740

3841
/**
@@ -98,6 +101,7 @@ export const Video = Node.create<VideoOptions>({
98101
allowFullscreen: true,
99102
upload: undefined,
100103
frameborder: false,
104+
resourceVideo: 'both',
101105
width: VIDEO_SIZE['size-medium'],
102106
HTMLAttributes: {
103107
class: 'iframe-wrapper',

src/extensions/Video/components/ActiveVideoButton.tsx

+25-14
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { useRef, useState } from 'react'
1+
import { useMemo, useRef, useState } from 'react'
22

33
import { ActionButton, Button, Input, Tabs, TabsContent, TabsList, TabsTrigger } from '@/components'
44
import { Dialog, DialogContent, DialogTitle, DialogTrigger } from '@/components/ui/dialog'
@@ -19,15 +19,20 @@ function ActionVideoButton(props: any) {
1919
const dialogVideo = useDialogVideo()
2020
const [error, setError] = useState<string>('')
2121

22+
const uploadOptions = useMemo(() => {
23+
const uploadOptions = props.editor.extensionManager.extensions.find(
24+
(extension: any) => extension.name === Video.name,
25+
)?.options
26+
27+
return uploadOptions
28+
}, [props.editor])
29+
2230
async function handleFile(event: any) {
2331
const files = event?.target?.files
2432
if (!props.editor || props.editor.isDestroyed || files.length === 0) {
2533
return
2634
}
2735
const file = files[0]
28-
const uploadOptions = props.editor.extensionManager.extensions.find(
29-
(extension: any) => extension.name === Video.name,
30-
)?.options
3136

3237
let src = ''
3338
if (uploadOptions.upload) {
@@ -84,17 +89,23 @@ function ActionVideoButton(props: any) {
8489
<DialogContent>
8590
<DialogTitle>{t('editor.video.dialog.title')}</DialogTitle>
8691

87-
<Tabs defaultValue="upload" activationMode="manual">
92+
<Tabs
93+
defaultValue={
94+
(uploadOptions?.resourceVideo === 'both' || uploadOptions?.resourceVideo === 'upload') ? 'upload' : 'link'
95+
}
96+
activationMode="manual"
97+
>
8898
<TabsList className="richtext-grid richtext-w-full richtext-grid-cols-2">
89-
<TabsTrigger value="upload">
90-
{t('editor.video.dialog.tab.upload')}
91-
{' '}
92-
</TabsTrigger>
93-
<TabsTrigger value="link">
94-
{' '}
95-
{t('editor.video.dialog.link')}
96-
{' '}
97-
</TabsTrigger>
99+
{(uploadOptions?.resourceVideo === 'both' || uploadOptions?.resourceVideo === 'upload') && (
100+
<TabsTrigger value="upload">
101+
{t('editor.video.dialog.tab.upload')}
102+
</TabsTrigger>
103+
)}
104+
{(uploadOptions?.resourceVideo === 'both' || uploadOptions?.resourceVideo === 'link') && (
105+
<TabsTrigger value="link">
106+
{t('editor.video.dialog.link')}
107+
</TabsTrigger>
108+
)}
98109
</TabsList>
99110

100111
<TabsContent value="upload">

src/locales/en.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -87,14 +87,14 @@ const locale = {
8787
'editor.image.dialog.form.alt': 'Alt',
8888
'editor.image.dialog.form.aspectRatio': 'Lock original aspect ratio',
8989
'editor.image.dialog.form.file': 'File',
90-
'editor.image.dialog.button.apply': 'apply',
90+
'editor.image.dialog.button.apply': 'Apply',
9191
'editor.video.tooltip': 'Video',
9292
'editor.video.dialog.tab.upload': 'Upload',
9393
'editor.video.dialog.uploading': 'Uploading',
9494
'editor.video.dialog.title': 'Embed or upload a video',
95-
'editor.video.dialog.link': 'link',
95+
'editor.video.dialog.link': 'Link',
9696
'editor.video.dialog.placeholder': 'Link',
97-
'editor.video.dialog.button.apply': 'apply',
97+
'editor.video.dialog.button.apply': 'Apply',
9898
'editor.table.tooltip': 'Table',
9999
'editor.table.menu.insert_table': 'Insert Table',
100100
'editor.table.menu.insert_table.with_header_row': 'With header row',

src/locales/pt-br.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -87,14 +87,14 @@ const locale = {
8787
'editor.image.dialog.form.alt': 'Alt',
8888
'editor.image.dialog.form.aspectRatio': 'Bloquear proporção original',
8989
'editor.image.dialog.form.file': 'Arquivo',
90-
'editor.image.dialog.button.apply': 'aplicar',
90+
'editor.image.dialog.button.apply': 'Aplicar',
9191
'editor.video.tooltip': 'Vídeo',
9292
'editor.video.dialog.tab.upload': 'Enviar',
9393
'editor.video.dialog.uploading': 'Enviando',
9494
'editor.video.dialog.title': 'Incorporar ou enviar um vídeo',
95-
'editor.video.dialog.link': 'link',
95+
'editor.video.dialog.link': 'Link',
9696
'editor.video.dialog.placeholder': 'Link',
97-
'editor.video.dialog.button.apply': 'aplicar',
97+
'editor.video.dialog.button.apply': 'Aplicar',
9898
'editor.table.tooltip': 'Tabela',
9999
'editor.table.menu.insert_table': 'Inserir tabela',
100100
'editor.table.menu.insert_table.with_header_row': 'Com linha de cabeçalho',

src/locales/vi.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -87,14 +87,14 @@ const locale = {
8787
'editor.image.dialog.form.alt': 'Alt',
8888
'editor.image.dialog.form.aspectRatio': 'Khóa tỷ lệ khung hình gốc',
8989
'editor.image.dialog.form.file': 'Tệp',
90-
'editor.image.dialog.button.apply': 'áp dụng',
90+
'editor.image.dialog.button.apply': 'Áp dụng',
9191
'editor.video.tooltip': 'Video',
9292
'editor.video.dialog.tab.upload': 'Tải lên',
9393
'editor.video.dialog.uploading': 'Đang tải lên',
9494
'editor.video.dialog.title': 'Nhúng hoặc tải lên video',
95-
'editor.video.dialog.link': 'liên kết',
95+
'editor.video.dialog.link': 'Liên kết',
9696
'editor.video.dialog.placeholder': 'Liên kết',
97-
'editor.video.dialog.button.apply': 'áp dụng',
97+
'editor.video.dialog.button.apply': 'Áp dụng',
9898
'editor.table.tooltip': 'Bảng',
9999
'editor.table.menu.insert_table': 'Chèn Bảng',
100100
'editor.table.menu.insert_table.with_header_row': 'Có hàng tiêu đề',

0 commit comments

Comments
 (0)