Skip to content

Commit

Permalink
上传视频类型过滤
Browse files Browse the repository at this point in the history
  • Loading branch information
hanaTsuk1 committed Nov 24, 2023
1 parent cc2c678 commit 7cd106f
Show file tree
Hide file tree
Showing 7 changed files with 135 additions and 25 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
"@date-io/date-fns": "^2.17.0",
"@mdi/font": "^7.3.67",
"@tauri-apps/api": "^1.3.0",
"@tiptap/core": "^2.1.12",
"@tiptap/extension-image": "^2.1.12",
"@tiptap/pm": "^2.1.12",
"@tiptap/starter-kit": "^2.1.12",
Expand Down
3 changes: 3 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

91 changes: 67 additions & 24 deletions src/components/shared/Tiptap.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,18 @@ import type { ChainedCommands } from '@tiptap/vue-3'
import { EditorContent, useEditor } from '@tiptap/vue-3'
import StarterKit from '@tiptap/starter-kit'
import Image from '@tiptap/extension-image'
import { isWebImage, uploadFile } from '@/modules/upload'
import { isImage, isVideo, isWebImage, isWebVideo, uploadFile } from '@/modules/upload'
import { Video } from '@/plugins/tiptap-video'
interface ImageNode {
src: string
alt: string
title: string
}
interface VideoNode {
src: string
}
const props = withDefaults(defineProps<{
content: string
Expand All @@ -28,6 +33,7 @@ const editor = useEditor({
extensions: [
StarterKit,
Image,
Video,
],
editorProps: {
attributes: {
Expand All @@ -40,29 +46,8 @@ const editor = useEditor({
const files = [...event.dataTransfer!.files]
const hasNonWebImage = files.some(file => !isWebImage(file))
if (hasNonWebImage) {
info({
text: t('upload.webImage'),
})
}
Promise.all(files.filter(isWebImage).map((file) => {
return new Promise<ImageNode>((resolve) => {
uploadFile(file).then(src =>
resolve({
src,
alt: file.name,
title: file.name,
}))
})
})).then((files) => {
editor.value?.commands.insertContent(files.map(attrs => ({
type: 'image',
attrs,
})))
})
uploadImage(files)
uploadVideo(files)
event.preventDefault()
},
Expand All @@ -72,6 +57,64 @@ const editor = useEditor({
},
})
function uploadImage(files: File[]) {
const images = files.filter(isImage)
const hasNonWebImage = images.some(file => !isWebImage(file))
if (hasNonWebImage) {
info({
text: t('upload.webImage'),
})
}
Promise.all(images.filter(isWebImage).map((file) => {
return new Promise<ImageNode>((resolve) => {
uploadFile(file).then(src =>
resolve({
src,
alt: file.name,
title: file.name,
}))
})
})).then((files) => {
if (!files.length)
return
editor.value?.commands.insertContent(files.map(attrs => ({
type: 'image',
attrs,
})))
})
}
function uploadVideo(files: File[]) {
const videos = files.filter(isVideo)
const hasNonWebVideo = videos.some(file => !isWebVideo(file))
if (hasNonWebVideo) {
info({
text: t('upload.webVideo'),
})
}
Promise.all(videos.filter(isWebVideo).map((file) => {
return new Promise<VideoNode>((resolve) => {
uploadFile(file).then(src =>
resolve({
src,
}))
})
})).then((files) => {
if (!files.length)
return
editor.value?.commands.insertContent(files.map(attrs => ({
type: 'video',
attrs,
})))
})
}
const utils = computed(() => [
{
icon: 'i-mdi:undo',
Expand Down
3 changes: 2 additions & 1 deletion src/locales/en-US.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -134,4 +134,5 @@ timeline:
filter: Filter Categories
reset: Reset Filter condition
upload:
webImage: 已过滤不支持的图片类型
webImage: Unsupported image types filtered
webVideo: Unsupported video types filtered
1 change: 1 addition & 0 deletions src/locales/zh-CN.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -135,3 +135,4 @@ timeline:
reset: 重置筛选条件
upload:
webImage: 已过滤不支持的图片类型
webVideo: 已过滤不支持的视频类型
12 changes: 12 additions & 0 deletions src/modules/upload/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,18 @@ export async function upload(name: string, buffer: ArrayBuffer) {
return convertFileSrc(path)
}

export function isImage(file: File) {
return file.type.includes('image')
}

export function isWebImage(file: File) {
return ['image/gif', 'image/jpeg', 'image/png', 'image/svg+xml', 'image/webp'].includes(file.type)
}

export function isVideo(file: File) {
return file.type.includes('video')
}

export function isWebVideo(file: File) {
return ['video/mp4', 'video/webm'].includes(file.type)
}
49 changes: 49 additions & 0 deletions src/plugins/tiptap-video.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { Node, mergeAttributes, nodeInputRule } from '@tiptap/core'

const inputRegex = /!\[(.+|:?)]\((\S+)(?:(?:\s+)["'](\S+)["'])?\)/

export interface VideoOptions {
HTMLAttributes: Record<string, any>
}

export const Video = Node.create<VideoOptions>({
name: 'video',
group: 'block',
draggable: true,
addOptions() {
return {
HTMLAttributes: {
controls: 'controls',
},
}
},
addAttributes() {
return {
src: {
default: null,
},
}
},
parseHTML() {
return [
{
tag: 'video',
},
]
},
renderHTML({ HTMLAttributes }) {
return ['video', mergeAttributes(this.options.HTMLAttributes, HTMLAttributes)]
},
addInputRules() {
return [
nodeInputRule({
find: inputRegex,
type: this.type,
getAttributes: (match) => {
const [, , src] = match
return { src }
},
}),
]
},
})

0 comments on commit 7cd106f

Please sign in to comment.