Browse Source

feat(frontend): 上传整季字幕页面添加“按字幕文件名排序映射”按钮 #704

Myon 2 years ago
parent
commit
b80971f7f6

+ 23 - 7
frontend/src/pages/library/tvs/BtnUploadMultipleForTv.vue

@@ -47,7 +47,18 @@
           <q-btn color="primary" label="选择文件" dense flat @click="() => qFile.$el.click()" />
         </div>
         <template v-else>
-          <q-btn color="primary" label="添加字幕文件" @click="() => qFile.$el.click()" class="q-mb-sm" />
+          <div class="row items-center q-gutter-x-md">
+            <q-btn color="primary" label="添加字幕文件" @click="() => qFile.$el.click()" class="q-mb-sm" />
+            <q-btn
+              color="primary"
+              outline
+              icon="low_priority"
+              label="按字幕文件名排序映射"
+              @click="resetMapByFilenameOrder"
+              title="不使用自动匹配,而是按照字幕文件名排序,从第一集往下开始映射"
+              class="q-mb-sm"
+            />
+          </div>
           <q-list separator>
             <q-item v-for="item in uploadFiles" :key="item.name">
               <q-item-section>{{ item.name }}</q-item-section>
@@ -164,7 +175,7 @@ const addMapForm = (file) => {
 };
 
 const handleNewFileAdded = (file) => {
-  if (/\.srt|\.ass|\.ssa|\.sbv|\.webvtt/.test(file.name)) {
+  if (/\.srt$|\.ass$|\.ssa$|\.sbv$|\.webvtt$/.test(file.name)) {
     if (!uploadFiles.value.some((f) => f.name === file.name)) {
       uploadFiles.value.push(file);
       addMapForm(file);
@@ -172,10 +183,11 @@ const handleNewFileAdded = (file) => {
   }
 };
 
-const handleFileChange = (val) => {
-  [].forEach.call(val, (file) => {
+const handleFileChange = (files) => {
+  [].forEach.call(files, (file) => {
     handleNewFileAdded(file);
   });
+  uploadFiles.value = uploadFiles.value.sort((a, b) => a.name.localeCompare(b.name));
 };
 
 const handleDragenter = (e) => {
@@ -190,9 +202,6 @@ const handleDragleave = (e) => {
 const handleDrop = (e) => {
   e.preventDefault();
   const { files } = e.dataTransfer;
-  [].forEach.call(files, (file) => {
-    handleNewFileAdded(file);
-  });
   handleFileChange(files);
   isDragover.value = false;
 };
@@ -202,6 +211,13 @@ const handleRemoveFile = (file) => {
   delete mapForm[file.name];
 };
 
+const resetMapByFilenameOrder = () => {
+  uploadFiles.value.forEach((file, index) => {
+    const item = props.items.find((i) => i.episode === index + 1);
+    mapForm[file.name] = item;
+  });
+};
+
 const handleBeforeShow = () => {
   uploadFiles.value = [];
   Object.keys(mapForm).forEach((key) => {

+ 15 - 4
frontend/src/utils/subtitle.js

@@ -4,14 +4,25 @@
  * @returns {null|number}
  */
 export const getEpisode = (filename) => {
-  const episode = filename.match(/s\d+e(\d+)/i);
+  let episode = filename.match(/s\d+e(\d+)/i);
   if (episode) {
     return parseInt(episode[1], 10);
   }
   // 第x集
-  const episode2 = filename.match(/第(\d+)集/i);
-  if (episode2) {
-    return parseInt(episode2[1], 10);
+  episode = filename.match(/第(\d+)(集|话|話)/i);
+  if (episode) {
+    return parseInt(episode[1], 10);
+  }
+
+  // [xx] 【xx】 匹配一些动画字幕组
+  episode = filename.match(/\[(\d+)\]/i);
+  if (episode) {
+    return parseInt(episode[1], 10);
+  }
+  episode = filename.match(/【(\d+)】/i);
+  if (episode) {
+    return parseInt(episode[1], 10);
   }
+
   return null;
 };