Skip to content

Commit

Permalink
Add: 辞書登録時・編集時に品詞の種類を設定できるようにした
Browse files Browse the repository at this point in the history
エンジン側には実装されてたのに UI になってなくてもったいなかったため
  • Loading branch information
tsukumijima committed Jan 2, 2025
1 parent 2ee34cd commit fc820c0
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 4 deletions.
51 changes: 49 additions & 2 deletions src/components/Dialog/DictionaryManageDialog.vue
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,22 @@
</div>
</div>
</div>
<div class="row q-pl-md q-mt-lg text-h6">品詞</div>
<div class="row q-pl-md q-mt-sm q-mb-md desc-row">
登録する単語の品詞を選択してください。
</div>
<div class="row q-pl-md q-pr-md">
<QSelect
v-model="wordType"
class="word-input"
outlined
:options="Object.entries(wordTypeLabels).map(([value, label]) => ({ value, label }))"
:disable="uiLocked"
dense
emitValue
mapOptions
/>
</div>
<div class="row q-pl-md q-mt-lg text-h6">単語優先度</div>
<div class="row q-pl-md q-mt-sm q-mb-lg desc-row">
単語を登録しても反映されない場合は優先度を高くしてください。
Expand Down Expand Up @@ -265,19 +281,20 @@

<script setup lang="ts">
import { computed, ref, watch } from "vue";
import { QInput } from "quasar";
import { QInput, QSelect } from "quasar";
import AudioAccent from "@/components/Talk/AudioAccent.vue";
import ContextMenu from "@/components/Menu/ContextMenu/Container.vue";
import { useRightClickContextMenu } from "@/composables/useRightClickContextMenu";
import { useStore } from "@/store";
import type { FetchAudioResult } from "@/store/type";
import { AccentPhrase, UserDictWord } from "@/openapi";
import { AccentPhrase, UserDictWord, WordTypes } from "@/openapi";
import {
convertHiraToKana,
convertLongVowel,
createKanaRegex,
} from "@/domain/japanese";
const defaultWordType = WordTypes.ProperNoun;
const defaultDictPriority = 5;
const props = defineProps<{
Expand Down Expand Up @@ -510,6 +527,30 @@ const computeDisplayAccent = () => {
return accent;
};
const wordType = ref<WordTypes>(defaultWordType);
const wordTypeLabels = {
[WordTypes.ProperNoun]: "固有名詞",
[WordTypes.CommonNoun]: "一般名詞",
[WordTypes.Verb]: "動詞",
[WordTypes.Adjective]: "形容詞",
[WordTypes.Suffix]: "接尾辞",
};
// 品詞フィールドから WordTypes を推定する関数
const getWordTypeFromPartOfSpeech = (dictData: UserDictWord): WordTypes => {
const { partOfSpeech, partOfSpeechDetail1 } = dictData;
if (partOfSpeech === "名詞") {
if (partOfSpeechDetail1 === "固有名詞") return WordTypes.ProperNoun;
if (partOfSpeechDetail1 === "接尾") return WordTypes.Suffix;
return WordTypes.CommonNoun;
}
if (partOfSpeech === "動詞") return WordTypes.Verb;
if (partOfSpeech === "形容詞") return WordTypes.Adjective;
// デフォルトは固有名詞
return WordTypes.ProperNoun;
};
const wordPriority = ref(defaultDictPriority);
const wordPriorityLabels = {
0: "最低",
Expand All @@ -527,11 +568,13 @@ const isWordChanged = computed(() => {
// 一旦代入することで、userDictそのものが更新された時もcomputedするようにする
const dict = userDict.value;
const dictData = dict[selectedId.value];
const currentWordType = getWordTypeFromPartOfSpeech(dictData);
return (
dictData &&
(dictData.surface !== surface.value ||
dictData.yomi !== yomi.value ||
dictData.accentType !== computeRegisteredAccent() ||
currentWordType !== wordType.value ||
dictData.priority !== wordPriority.value)
);
});
Expand All @@ -549,6 +592,7 @@ const saveWord = async () => {
surface: surface.value,
pronunciation: yomi.value,
accentType: accent,
wordType: wordType.value,
priority: wordPriority.value,
});
} catch {
Expand All @@ -574,6 +618,7 @@ const saveWord = async () => {
surface: surface.value,
pronunciation: yomi.value,
accentType: accent,
wordType: wordType.value,
priority: wordPriority.value,
}),
);
Expand Down Expand Up @@ -663,6 +708,7 @@ const selectWord = (id: string) => {
selectedId.value = id;
surface.value = userDict.value[id].surface;
void setYomi(userDict.value[id].yomi, true);
wordType.value = getWordTypeFromPartOfSpeech(userDict.value[id]);
wordPriority.value = userDict.value[id].priority;
toWordSelectedState();
};
Expand All @@ -681,6 +727,7 @@ const toInitialState = () => {
selectedId.value = "";
surface.value = "";
void setYomi("");
wordType.value = defaultWordType;
wordPriority.value = defaultDictPriority;
// 辞書の最初の項目を選択する
Expand Down
6 changes: 4 additions & 2 deletions src/store/dictionary.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ export const dictionaryStore = createPartialStore<DictionaryStoreTypes>({
ADD_WORD: {
async action(
{ state, actions },
{ surface, pronunciation, accentType, priority },
{ surface, pronunciation, accentType, wordType, priority },
) {
// 同じ単語IDで登録するために、1つのエンジンで登録したあと全エンジンに同期する。
const engineId: EngineId | undefined = state.engineIds[0];
Expand All @@ -80,6 +80,7 @@ export const dictionaryStore = createPartialStore<DictionaryStoreTypes>({
surface,
pronunciation,
accentType,
wordType,
priority,
}),
);
Expand All @@ -91,7 +92,7 @@ export const dictionaryStore = createPartialStore<DictionaryStoreTypes>({
REWRITE_WORD: {
async action(
{ state, actions },
{ wordUuid, surface, pronunciation, accentType, priority },
{ wordUuid, surface, pronunciation, accentType, wordType, priority },
) {
if (state.engineIds.length === 0)
throw new Error("At least one engine must be registered");
Expand All @@ -106,6 +107,7 @@ export const dictionaryStore = createPartialStore<DictionaryStoreTypes>({
surface,
pronunciation,
accentType,
wordType,
priority,
}),
);
Expand Down
3 changes: 3 additions & 0 deletions src/store/type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import {
UserDictWord,
MorphableTargetInfo,
FrameAudioQuery,
WordTypes,
Note as NoteForRequestToEngine,
} from "@/openapi";
import {
Expand Down Expand Up @@ -2253,6 +2254,7 @@ export type DictionaryStoreTypes = {
surface: string;
pronunciation: string;
accentType: number;
wordType: WordTypes;
priority: number;
}): Promise<void>;
};
Expand All @@ -2262,6 +2264,7 @@ export type DictionaryStoreTypes = {
surface: string;
pronunciation: string;
accentType: number;
wordType: WordTypes;
priority: number;
}): Promise<void>;
};
Expand Down

0 comments on commit fc820c0

Please sign in to comment.