Skip to content

Commit

Permalink
エラーを全部解消
Browse files Browse the repository at this point in the history
  • Loading branch information
Hiroshiba committed Sep 24, 2023
1 parent 32ad3dc commit 2dd1a0d
Show file tree
Hide file tree
Showing 6 changed files with 79 additions and 39 deletions.
10 changes: 8 additions & 2 deletions src/components/Sing/CharacterMenuButton.vue
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ import { defineComponent, computed, ref } from "vue";
import { debounce } from "quasar";
import { useStore } from "@/store";
import { base64ImageToUri } from "@/helpers/imageHelper";
import { SpeakerId, StyleId } from "@/type/preload";
export default defineComponent({
name: "CharacterMenuButton",
Expand All @@ -169,7 +170,7 @@ export default defineComponent({
subMenuOpenFlags.value = arr;
}, 100);
const changeStyleId = (speakerUuid: string, styleId: number) => {
const changeStyleId = (speakerUuid: SpeakerId, styleId: StyleId) => {
const engineId = store.state.engineIds.find((_engineId) =>
(store.state.characterInfos[_engineId] ?? []).some(
(characterInfo) =>
Expand All @@ -196,9 +197,14 @@ export default defineComponent({
(x) => x.speakerUuid === speakerUuid
)?.defaultStyleId;
return characterInfo?.metas.styles.find(
const defaultStyle = characterInfo?.metas.styles.find(
(style) => style.styleId === defaultStyleId
);
if (defaultStyle == undefined)
throw new Error("defaultStyle == undefined");
return defaultStyle;
};
const selectedCharacterInfo = computed(() => {
Expand Down
29 changes: 22 additions & 7 deletions src/components/Sing/MenuBar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -35,23 +35,29 @@ export type MenuItemRoot = SingMenuItemBase<"root"> & {
onClick: () => void;
subMenu: MenuItemData[];
icon?: string;
disabled?: boolean;
disableWhenUiLocked: boolean;
disablreloadingLocked?: boolean;
};
export type MenuItemButton = SingMenuItemBase<"button"> & {
onClick: () => void;
icon?: string;
disabled?: boolean;
disableWhenUiLocked: boolean;
disablreloadingLocked?: boolean;
};
export type MenuItemCheckbox = SingMenuItemBase<"checkbox"> & {
checked: ComputedRef<boolean>;
onClick: () => void;
checked: ComputedRef<boolean>;
icon?: string;
disabled?: boolean;
disableWhenUiLocked: boolean;
disablreloadingLocked?: boolean;
};
export type MenuItemData =
| MenuItemSeparator
| MenuItemRoot
| MenuItemButton
| MenuItemCheckbox;
export type MenuItemData = MenuItemSeparator | MenuItemRoot | MenuItemButton;
export type MenuItemType = MenuItemData["type"];
Expand Down Expand Up @@ -105,7 +111,7 @@ export default defineComponent({
};
const openHelpDialog = () => {
store.dispatch("IS_HELP_DIALOG_OPEN", {
store.dispatch("SET_DIALOG_OPEN", {
isHelpDialogOpen: true,
});
};
Expand All @@ -121,34 +127,39 @@ export default defineComponent({
onClick: () => {
closeAllDialog();
},
disableWhenUiLocked: false,
subMenu: [
{
type: "button",
label: "新規",
onClick: () => {
createNewSingProject();
},
disableWhenUiLocked: true,
},
{
type: "button",
label: "開く",
onClick: () => {
openSingProject();
},
disableWhenUiLocked: true,
},
{
type: "button",
label: "保存",
onClick: () => {
saveSingProject();
},
disableWhenUiLocked: true,
},
{
type: "button",
label: "別名で保存",
onClick: () => {
saveAsSingProject();
},
disableWhenUiLocked: true,
},
{ type: "separator" },
{
Expand All @@ -157,13 +168,15 @@ export default defineComponent({
onClick: () => {
importMidiFile();
},
disableWhenUiLocked: true,
},
{
type: "button",
label: "MusicXML読み込み",
onClick: () => {
importMusicXMLFile();
},
disableWhenUiLocked: true,
},
{ type: "separator" },
{
Expand All @@ -172,6 +185,7 @@ export default defineComponent({
onClick: () => {
exportWaveFile();
},
disableWhenUiLocked: true,
},
],
},
Expand All @@ -185,6 +199,7 @@ export default defineComponent({
openHelpDialog();
}
},
disableWhenUiLocked: false,
},
]);
Expand Down
1 change: 0 additions & 1 deletion src/components/Sing/ScoreSequencer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
@mousemove="handleMouseMove"
@mouseup="handleMouseUp"
@dblclick="addNote"
@dblclick.prevent.stop="removeNote"
>
<!-- 鍵盤 -->
<sequencer-keys />
Expand Down
4 changes: 2 additions & 2 deletions src/components/Sing/SequencerNote.vue
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ export default defineComponent({
store.dispatch("REMOVE_NOTE", { id: props.note.id });
};
const setLyric = (event: InputEvent) => {
const setLyric = (event: Event) => {
if (!(event.target instanceof HTMLInputElement)) {
return;
}
Expand Down Expand Up @@ -187,7 +187,7 @@ export default defineComponent({
.sequencer-note-lyric {
background: white;
border: 0;
border-bottom: 1px solid colors.$primary-light;
border-bottom: 1px solid colors.$primary;
color: colors.$display;
font-size: 12px;
font-weight: bold;
Expand Down
66 changes: 43 additions & 23 deletions src/store/singing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,14 @@ import {
PolySynth,
Transport,
} from "@/infrastructures/AudioRenderer";
import { WriteFileErrorResult } from "@/type/preload";
import { EngineId, StyleId } from "@/type/preload";
import {
getDoremiFromMidi,
midiToFrequency,
round,
} from "@/helpers/singHelper";
import { AudioQuery } from "@/openapi";
import { ResultError, getValueOrThrow } from "@/type/result";

const ticksToSecondsForConstantBpm = (
resolution: number,
Expand Down Expand Up @@ -160,8 +161,8 @@ const createPromiseThatResolvesWhen = (
};

type Singer = {
readonly engineId: string;
readonly styleId: number;
readonly engineId: EngineId;
readonly styleId: StyleId;
};

type Phrase = {
Expand Down Expand Up @@ -287,7 +288,7 @@ export const singingStore = createPartialStore<SingingStoreTypes>({
SET_SINGER: {
mutation(
state,
{ engineId, styleId }: { engineId: string; styleId: number }
{ engineId, styleId }: { engineId: EngineId; styleId: StyleId }
) {
state.engineId = engineId;
state.styleId = styleId;
Expand Down Expand Up @@ -1238,7 +1239,9 @@ export const singingStore = createPartialStore<SingingStoreTypes>({
if (!filePath) return;
}

const midiData = await window.electron.readFile({ filePath });
const midiData = getValueOrThrow(
await window.electron.readFile({ filePath })
);
const midi = new Midi(midiData);

const score = await dispatch("GET_EMPTY_SCORE");
Expand Down Expand Up @@ -1336,11 +1339,11 @@ export const singingStore = createPartialStore<SingingStoreTypes>({
}

let xmlStr = new TextDecoder("utf-8").decode(
await window.electron.readFile({ filePath })
getValueOrThrow(await window.electron.readFile({ filePath }))
);
if (xmlStr.indexOf("\ufffd") > -1) {
xmlStr = new TextDecoder("shift-jis").decode(
await window.electron.readFile({ filePath })
getValueOrThrow(await window.electron.readFile({ filePath }))
);
}

Expand Down Expand Up @@ -1684,20 +1687,25 @@ export const singingStore = createPartialStore<SingingStoreTypes>({
return buffer;
};

const generateWriteErrorMessage = (
writeFileErrorResult: WriteFileErrorResult
) => {
if (writeFileErrorResult.code) {
const code = writeFileErrorResult.code.toUpperCase();
function generateWriteErrorMessage(writeFileResult: ResultError) {
if (writeFileResult.code) {
const code = writeFileResult.code.toUpperCase();

if (code.startsWith("ENOSPC")) {
return "空き容量が足りません。";
}

if (code.startsWith("EACCES")) {
return "ファイルにアクセスする許可がありません。";
}

if (code.startsWith("EBUSY")) {
return "ファイルが開かれています。";
}
}
return `何らかの理由で失敗しました。${writeFileErrorResult.message}`;
};

return `何らかの理由で失敗しました。${writeFileResult.message}`;
}

if (!audioRenderer) {
throw new Error("audioRenderer is undefined.");
Expand Down Expand Up @@ -1739,7 +1747,7 @@ export const singingStore = createPartialStore<SingingStoreTypes>({
if (state.savingSetting.avoidOverwrite) {
let tail = 1;
const name = filePath.slice(0, filePath.length - 4);
while (await dispatch("CHECK_FILE_EXISTS", { file: filePath })) {
while (await window.electron.checkFileExists(filePath)) {
filePath = name + "[" + tail.toString() + "]" + ".wav";
tail += 1;
}
Expand Down Expand Up @@ -1794,16 +1802,28 @@ export const singingStore = createPartialStore<SingingStoreTypes>({
);
const waveFileData = convertToWavFileData(audioBuffer);

const writeFileResult = window.electron.writeFile({
filePath,
buffer: waveFileData,
}); // 失敗した場合、WriteFileErrorResultオブジェクトが返り、成功時はundefinedが反る
if (writeFileResult) {
window.electron.logError(new Error(writeFileResult.message));
try {
await window.electron
.writeFile({
filePath,
buffer: waveFileData,
})
.then(getValueOrThrow);
} catch (e) {
window.electron.logError(e);
if (e instanceof ResultError) {
return {
result: "WRITE_ERROR",
path: filePath,
errorMessage: generateWriteErrorMessage(e),
};
}
return {
result: "WRITE_ERROR",
result: "UNKNOWN_ERROR",
path: filePath,
errorMessage: generateWriteErrorMessage(writeFileResult),
errorMessage:
(e instanceof Error ? e.message : String(e)) ||
"不明なエラーが発生しました。",
};
}

Expand Down
8 changes: 4 additions & 4 deletions src/store/type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -741,8 +741,8 @@ export type AudioPlayerStoreTypes = {
*/

export type SingingStoreState = {
engineId?: string;
styleId?: number;
engineId?: EngineId;
styleId?: StyleId;
score?: Score;
// NOTE: UIの状態などは分割・統合した方がよさそうだが、ボイス側と混在させないためいったん局所化する
isShowSinger: boolean;
Expand Down Expand Up @@ -770,8 +770,8 @@ export type SingingStoreTypes = {
};

SET_SINGER: {
mutation: { engineId: string; styleId: number };
action(payload: { engineId?: string; styleId?: number }): void;
mutation: { engineId: EngineId; styleId: StyleId };
action(payload: { engineId?: EngineId; styleId?: StyleId }): void;
};

GET_EMPTY_SCORE: {
Expand Down

0 comments on commit 2dd1a0d

Please sign in to comment.