123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112 |
- <script setup lang="ts">
- import { ref, inject, type Ref } from "vue";
- import { VideoCamera } from "@element-plus/icons-vue";
- import { DropdownToolbar } from "md-editor-v3";
- import { Link } from "@element-plus/icons-vue";
- import { S3Client, PutObjectCommand } from "@aws-sdk/client-s3";
- import { v4 as uuid4 } from "uuid";
- const prefix = "md-editor";
- const s3 = inject<InstanceType<typeof S3Client>>("s3");
- const editorLoading = inject<Ref<boolean>>("editorLoading");
- const props = defineProps<{
- insert?: Function;
- }>();
- const showDropdown = ref(false);
- const showDialog = ref(false);
- const linkInput = ref("");
- const onClickMenuLink = () => {
- showDropdown.value = false;
- showDialog.value = true;
- };
- const selectFile = (contentType: string, multiple: boolean) => {
- return new Promise((resolve) => {
- let input = document.createElement("input");
- input.type = "file";
- input.multiple = multiple;
- input.accept = contentType;
- input.onchange = (_) => {
- let files = Array.from(input.files);
- if (multiple) resolve(files);
- else resolve(files[0]);
- };
- input.click();
- });
- };
- const onClickMenuSelect = async () => {
- showDropdown.value = false;
- const file = await selectFile("video/*", false);
- const key = `${uuid4()}::${file.name}`;
- const command = new PutObjectCommand({
- Bucket: import.meta.env.VITE_DOCS_MEDIA_BUCKET,
- Key: key,
- Body: file,
- ACL: "public-read",
- });
- editorLoading!.value = true;
- await s3!.send(command);
- editorLoading!.value = false;
- insert(
- `https://${import.meta.env.VITE_DOCS_MEDIA_BUCKET}.s3.amazonaws.com/${key}`
- );
- };
- const onConfirmDialog = async () => {
- // FIXME check link format?
- await insert(linkInput.value);
- linkInput.value = "";
- showDialog.value = false;
- };
- const insert = (url: string) => {
- // TEST
- // const url = `https://woolyss.com/f/av1-opus-sita.webm`;
- props.insert?.(() => ({
- targetValue: `<video src="${url}" width="100%" controls></video>`,
- }));
- };
- </script>
- <template>
- <DropdownToolbar title="video" :visible="showDropdown" :onChange="(v) => (showDropdown = v)">
- <template #trigger>
- <VideoCamera width="18" />
- </template>
- <template #overlay>
- <ul :class="`${prefix}-menu`">
- <li :class="`${prefix}-menu-item ${prefix}-menu-item-title`" @click="onClickMenuLink">
- 输入链接
- </li>
- <li :class="`${prefix}-menu-item ${prefix}-menu-item-title`" @click="onClickMenuSelect">
- 选择文件
- </li>
- </ul>
- </template>
- </DropdownToolbar>
- <el-dialog v-model="showDialog" title="添加视频">
- <div>
- <el-input v-model="linkInput" placeholder="https://woolyss.com/f/av1-opus-sita.webm">
- <template #prepend>
- <el-icon>
- <Link />
- </el-icon>
- </template>
- </el-input>
- </div>
- <template #footer>
- <div>
- <el-button @click="showDialog = false">取消</el-button>
- <el-button type="primary" @click="onConfirmDialog"> 确认 </el-button>
- </div>
- </template>
- </el-dialog>
- </template>
|