Skip to content

Commit

Permalink
增加切割单词功能
Browse files Browse the repository at this point in the history
  • Loading branch information
Steve-xmh committed Feb 14, 2024
1 parent 389dd8c commit 75249a9
Show file tree
Hide file tree
Showing 5 changed files with 87 additions and 46 deletions.
2 changes: 2 additions & 0 deletions src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@
<ImportFromDBDialog/>
<MetadataDialog/>
<SettingsModal/>
<SplitWordModal/>
<ServiceWorkerUpdater v-if="enableSW"/>
<!-- <SplitWordModal /> -->
</template>
Expand All @@ -88,6 +89,7 @@ import ImportPlainTextModal from "./components/modals/ImportPlainTextModal.vue";
import {useI18n} from "vue-i18n";
import MetadataDialog from "./components/modals/MetadataDialog.vue";
import SettingsModal from "./components/modals/SettingsModal.vue";
import SplitWordModal from "./components/modals/SplitWordModal.vue";
const LyricEditor = defineAsyncComponent(() => import("./components/LyricEditor.vue"));
const LyricSyncEditor = defineAsyncComponent(() => import("./components/LyricSyncEditor.vue"));
Expand Down
9 changes: 7 additions & 2 deletions src/components/ContextMenu.vue
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,13 @@
@click="() => {lyric.removeWord(lyricLineMenu.selectedLine, lyricLineMenu.selectedWord); lyricLineMenu.show = false;}">
<i18n-t keypath="contextMenu.deleteWord"/>
</NEl>
<NEl tag="button" @click="showWipNotification">
<NEl tag="button" @click="() => {dialogs.splitWord = true; lyricLineMenu.show = false;}">
<i18n-t keypath="contextMenu.splitWord"/>
</NEl>
<NEl v-if="lyric.lyrics[lyricLineMenu.selectedLine]?.words?.length > 1" tag="button"
@click="() => {dialogs.concatWords = true; lyricLineMenu.show = false;}">
<i18n-t keypath="contextMenu.concatWords" @click="showWipNotification"/>
</NEl>
<NDivider style="margin: 4px 0"/>
<NEl tag="button" @click="() => {lyric.removeLine(lyricLineMenu.selectedLine); lyricLineMenu.show = false;}">
<i18n-t keypath="contextMenu.deleteLine"/>
Expand All @@ -53,7 +57,7 @@
<script setup lang="tsx">
import {NDivider, NEl, NPopover, useNotification} from "naive-ui";
import {onMounted} from "vue";
import {useEditingLyric, useRightClickLyricLine} from "../store";
import {useDialogs, useEditingLyric, useRightClickLyricLine} from "../store";
import type {DropdownMixedOption} from "naive-ui/es/dropdown/src/interface";
import {i18n} from '../i18n';
import ContextMenuWordEdit from "./ContextMenuWordEdit.vue";
Expand All @@ -76,6 +80,7 @@ const wordOnlyContextMenu = [
const lyricLineMenu = useRightClickLyricLine();
const notify = useNotification();
const lyric = useEditingLyric();
const dialogs = useDialogs();
function showWipNotification() {
notify.error({
Expand Down
117 changes: 73 additions & 44 deletions src/components/modals/SplitWordModal.vue
Original file line number Diff line number Diff line change
Expand Up @@ -10,71 +10,100 @@
-->

<template>
<NModal :closable="!submitData.processing" :show="dialogs.submitLyric" :title="t('splitWordModal.title')"
<NModal :segmented="{ footer: 'soft' }" :show="dialogs.splitWord"
preset="card" style="max-width: 600px;" transform-origin="center"
@close="dialogs.submitLyric = false">
:title="t('splitWordModal.title')"
@close="dialogs.splitWord = false">
<NAlert style="margin-bottom: 1em" type="info">
<i18n-t keypath="splitWordModal.tip"/>
</NAlert>
<NFormItem label="原始单词">
<NInput v-model:value="splitWord"/>
</NFormItem>
<NFormItem label="分隔符">
<NInput v-model:value="splitDelimiter"/>
</NFormItem>
<NSpace vertical>

<div>
<i18n-t keypath="splitWordModal.splitResultPreview"/>
</div>
<div class="result-preview">
<span v-for="word in splitResult">
{{ word }}
</span>
</div>
</NSpace>
<template #footer>
<NButton
:disabled="submitData.processing || !submitData.name || !submitData.ids || lyric.lyrics.length === 0"
type="primary" @click="uploadAndSubmit">
type="primary"
@click="processWordSplit"
>
<i18n-t keypath="splitWordModal.splitBtn"/>
</NButton>
</template>
</NModal>
</template>

<script setup lang="ts">
import {NButton, NModal, NSpace, useNotification} from 'naive-ui';
import {useDialogs, useEditingLyric} from '../../store';
import {reactive} from "vue";
import {NAlert, NButton, NFormItem, NInput, NModal, NSpace} from 'naive-ui';
import {useDialogs, useEditingLyric, useRightClickLyricLine} from '../../store';
import {computed, ref, watchEffect} from "vue";
import {useI18n} from "vue-i18n";
import type {LyricWord} from "../../utils/ttml-types";
const lyric = useEditingLyric();
const notify = useNotification();
const rightClick = useRightClickLyricLine();
const dialogs = useDialogs();
const splitWord = ref("");
const splitDelimiter = ref("\\");
const {t} = useI18n({useScope: "global"});
const submitData = reactive({
name: "",
ids: "",
submitReason: "新歌词提交",
comment: "",
processing: false,
const originWord = computed(() => lyric.lyrics[rightClick.selectedLine]?.words?.[rightClick.selectedWord]?.word ?? "");
const splitResult = computed(() => {
const word = splitWord.value;
const delimiter = splitDelimiter.value;
if (word && delimiter) {
return word.split(delimiter);
}
return [word];
});
async function uploadAndSubmit() {
if (submitData.processing) return;
submitData.processing = true;
try {
const lyricData = encodeURIComponent(lyric.toTTML());
const lyricUrl = await fetch("https://dpaste.org/api/", {
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded"
},
body: "format=url&lexer=xml&expires=3600&filename=lyric.ttml&content=" + lyricData
}).then(v => v.text()).then(v => v.trim() + "/raw");
const issueUrl = new URL("https://github.com/Steve-xmh/amll-ttml-db/issues/new");
issueUrl.searchParams.append("labels", "歌词提交/补正");
issueUrl.searchParams.append("template", "submit-lyric.yml");
issueUrl.searchParams.append("title", "[歌词提交/修正] " + submitData.name);
issueUrl.searchParams.append("song-name", submitData.name);
issueUrl.searchParams.append("song-id", submitData.ids);
issueUrl.searchParams.append("ttml-download-url", lyricUrl);
issueUrl.searchParams.append("upload-reason", submitData.submitReason);
issueUrl.searchParams.append("comment", submitData.comment);
open(issueUrl.toString());
} catch (err) {
console.warn("提交失败", err);
notify.error({
title: "歌词提交失败!",
content: `错误原因:\n${err}`,
});
function processWordSplit() {
const line = lyric.lyrics[rightClick.selectedLine];
if (line) {
const joinResult = splitResult.value.join("");
const newWords: LyricWord[] = splitResult.value.map(word => ({word, startTime: 0, endTime: 0}));
const startTime = line.words[rightClick.selectedWord]?.startTime ?? 0;
const endTime = line.words[rightClick.selectedWord]?.endTime ?? 0;
const timeStep = (endTime - startTime) / joinResult.length;
let wordIndex = 0;
for (const newWord of newWords) {
newWord.startTime = startTime + timeStep * wordIndex;
newWord.endTime = startTime + timeStep * (wordIndex + newWord.word.length);
wordIndex += newWord.word.length;
}
line.words.splice(rightClick.selectedWord, 1, ...newWords);
lyric.record();
}
submitData.processing = false;
dialogs.splitWord = false;
}
watchEffect(() => {
splitWord.value = originWord.value;
});
</script>

<style lang="sass" scoped>
.result-preview
max-width: 100%
overflow: auto hidden
display: flex
gap: 1em
white-space: nowrap
> *
border: solid 1px #9993
border-radius: 4px
padding: 0 0.5em
</style>
3 changes: 3 additions & 0 deletions src/i18n/zh-cn.ts
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@ export const zhCN = {
toggleDuetLine: "切换对唱人声歌词",
deleteWord: "删除选定单词",
splitWord: "切割当前单词",
concatWords: "拼接单词",
wipNotification: {
title: "功能暂未实现",
content: "请静候作者爆肝实现吧~",
Expand Down Expand Up @@ -200,7 +201,9 @@ export const zhCN = {
},
splitWordModal: {
title: "拆分单词",
tip: "拆分后新单词将会按自身单词字符平均分配原单词的始末时间,如有空拍则会被清除",
splitBtn: "拆分",
splitResultPreview: "拆分结果预览",
},
importPlainTextModal: {
title: "从纯文本导入歌词",
Expand Down
2 changes: 2 additions & 0 deletions src/store/dialogs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ export const useDialogs = defineStore("dialogs", {
state: () => ({
importFromDB: false,
submitLyric: false,
splitWord: false,
concatWords: true,
editLyricInfo: false,
importFromText: false,
metadata: false,
Expand Down

0 comments on commit 75249a9

Please sign in to comment.