refactor: uploading content in lesson
This commit is contained in:
@@ -134,6 +134,7 @@ const addQuiz = (value) => {
|
||||
}
|
||||
|
||||
const addFile = (data) => {
|
||||
console.log(data)
|
||||
getCurrentEditor().caret.setToLastBlock('end', 0)
|
||||
getCurrentEditor().blocks.insert('upload', data)
|
||||
}
|
||||
|
||||
57
frontend/src/components/UploadPlugin.vue
Normal file
57
frontend/src/components/UploadPlugin.vue
Normal file
@@ -0,0 +1,57 @@
|
||||
<template>
|
||||
<FileUploader
|
||||
:fileTypes="['image/*', 'video/*', 'audio/*', '.pdf']"
|
||||
:validateFile="validateFile"
|
||||
@success="(data) => addFile(data)"
|
||||
ref="fileUploader"
|
||||
class="hide"
|
||||
/>
|
||||
</template>
|
||||
<script setup>
|
||||
import { FileUploader } from 'frappe-ui'
|
||||
import { onMounted, ref, nextTick } from 'vue'
|
||||
|
||||
const fileUploader = ref(null)
|
||||
const emit = defineEmits(['fileUploaded'])
|
||||
|
||||
const props = defineProps({
|
||||
wrapper: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
onFileUploaded: {
|
||||
type: Function,
|
||||
required: true,
|
||||
},
|
||||
})
|
||||
|
||||
onMounted(async () => {
|
||||
await nextTick()
|
||||
const fileInput = fileUploader.value.$el.querySelector('input[type="file"]')
|
||||
if (fileInput) {
|
||||
fileInput.click()
|
||||
}
|
||||
})
|
||||
|
||||
const addFile = (file) => {
|
||||
props.onFileUploaded({
|
||||
file_url: file.file_url,
|
||||
file_type: file.file_type,
|
||||
})
|
||||
}
|
||||
|
||||
const validateFile = (file) => {
|
||||
let extension = file.name.split('.').pop().toLowerCase()
|
||||
if (!['jpg', 'jpeg', 'png', 'mp4', 'mov', 'mp3', 'pdf'].includes(extension)) {
|
||||
return 'Only image and video files are allowed.'
|
||||
}
|
||||
}
|
||||
|
||||
const isVideo = (type) => {
|
||||
return ['mov', 'mp4', 'avi', 'mkv', 'webm'].includes(type.toLowerCase())
|
||||
}
|
||||
|
||||
const isAudio = (type) => {
|
||||
return ['mp3', 'wav', 'ogg'].includes(type.toLowerCase())
|
||||
}
|
||||
</script>
|
||||
2
frontend/src/utils/Upload.vue
Normal file
2
frontend/src/utils/Upload.vue
Normal file
@@ -0,0 +1,2 @@
|
||||
<template></template>
|
||||
<script setup></script>
|
||||
@@ -62,7 +62,7 @@ export class CodeBox {
|
||||
|
||||
static get toolbox() {
|
||||
const app = createApp({
|
||||
render: () => h(Code, { size: 24, strokeWidth: 2, color: 'black' }),
|
||||
render: () => h(Code, { size: 18, strokeWidth: 1.5, color: 'black' }),
|
||||
});
|
||||
|
||||
const div = document.createElement('div');
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
import Embed from '@editorjs/embed'
|
||||
import VideoBlock from '@/components/VideoBlock.vue'
|
||||
import { createApp } from 'vue'
|
||||
|
||||
export class CustomEmbed extends Embed {
|
||||
render() {
|
||||
const container = super.render()
|
||||
const { service, source, embed } = this.data
|
||||
|
||||
if (service === 'youtube' || service === 'vimeo') {
|
||||
// Remove the iframe or existing embed content
|
||||
container.innerHTML = ''
|
||||
|
||||
// Create a placeholder element for Vue component
|
||||
const vueContainer = document.createElement('div')
|
||||
vueContainer.setAttribute('data-service', service)
|
||||
vueContainer.setAttribute('data-video-id', this.data.source)
|
||||
|
||||
// Append the Vue placeholder
|
||||
container.appendChild(vueContainer)
|
||||
console.log(source)
|
||||
// Mount the Vue component (using a global Vue instance)
|
||||
const app = createApp(VideoBlock, {
|
||||
file: source,
|
||||
type: 'video/youtube',
|
||||
})
|
||||
app.mount(vueContainer)
|
||||
}
|
||||
|
||||
return container
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,9 @@
|
||||
import AudioBlock from '@/components/AudioBlock.vue'
|
||||
import VideoBlock from '@/components/VideoBlock.vue'
|
||||
import { createApp } from 'vue'
|
||||
import UploadPlugin from '@/components/UploadPlugin.vue'
|
||||
import { h, createApp, inject } from 'vue'
|
||||
import { Upload as UploadIcon } from 'lucide-vue-next'
|
||||
import translationPlugin from '../translation'
|
||||
|
||||
export class Upload {
|
||||
constructor({ data, api, readOnly }) {
|
||||
@@ -8,17 +11,38 @@ export class Upload {
|
||||
this.readOnly = readOnly
|
||||
}
|
||||
|
||||
static get toolbox() {
|
||||
const app = createApp({
|
||||
render: () =>
|
||||
h(UploadIcon, { size: 18, strokeWidth: 1.5, color: 'black' }),
|
||||
})
|
||||
|
||||
const div = document.createElement('div')
|
||||
app.mount(div)
|
||||
|
||||
return {
|
||||
title: 'Upload',
|
||||
icon: div.innerHTML,
|
||||
}
|
||||
}
|
||||
|
||||
static get isReadOnlySupported() {
|
||||
return true
|
||||
}
|
||||
|
||||
render() {
|
||||
this.wrapper = document.createElement('div')
|
||||
this.renderUpload(this.data)
|
||||
|
||||
if (this.data && this.data.file_url) {
|
||||
this.renderFile(this.data)
|
||||
} else {
|
||||
this.renderFileUploader()
|
||||
}
|
||||
|
||||
return this.wrapper
|
||||
}
|
||||
|
||||
renderUpload(file) {
|
||||
renderFile(file) {
|
||||
if (this.isVideo(file.file_type)) {
|
||||
const app = createApp(VideoBlock, {
|
||||
file: file.file_url,
|
||||
@@ -44,6 +68,26 @@ export class Upload {
|
||||
}
|
||||
}
|
||||
|
||||
renderFileUploader() {
|
||||
const app = createApp(UploadPlugin, {
|
||||
wrapper: this.wrapper,
|
||||
onFileUploaded: (file) => {
|
||||
this.data.file_url = file.file_url
|
||||
this.data.file_type = file.file_type
|
||||
this.renderFile(file)
|
||||
},
|
||||
})
|
||||
app.use(translationPlugin)
|
||||
app.mount(this.wrapper)
|
||||
}
|
||||
|
||||
validate(savedData) {
|
||||
if (!savedData.file_url || !savedData.file_type) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
save(blockContent) {
|
||||
return {
|
||||
file_url: this.data.file_url,
|
||||
|
||||
2165
frontend/yarn.lock
2165
frontend/yarn.lock
File diff suppressed because it is too large
Load Diff
@@ -2,7 +2,7 @@
|
||||
"name": "frappe_lms",
|
||||
"version": "1.0.0",
|
||||
"description": "Easy to use, open-source, Learning Management System",
|
||||
"workspaces1": [
|
||||
"workspaces": [
|
||||
"frappe-ui",
|
||||
"frontend"
|
||||
],
|
||||
|
||||
Reference in New Issue
Block a user