Skip to content

Commit

Permalink
fix: ドラッグアンドドロップでプロジェクトファイルやテキストファイルが読み込めなかったのを直す (#2433)
Browse files Browse the repository at this point in the history
  • Loading branch information
Hiroshiba authored Jan 5, 2025
1 parent 15c3d36 commit df4ad34
Show file tree
Hide file tree
Showing 13 changed files with 93 additions and 36 deletions.
3 changes: 3 additions & 0 deletions src/backend/browser/sandbox.ts
Original file line number Diff line number Diff line change
Expand Up @@ -280,4 +280,7 @@ export const api: Sandbox = {
reloadApp(/* obj: { isMultiEngineOffMode: boolean } */) {
throw new Error(`Not supported on Browser version: reloadApp`);
},
getPathForFile(/* file: File */) {
throw new Error(`Not supported on Browser version: getPathForFile`);
},
};
7 changes: 6 additions & 1 deletion src/backend/electron/preload.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { contextBridge, ipcRenderer } from "electron";
import { contextBridge, ipcRenderer, webUtils } from "electron";
import type { IpcRendererInvoke } from "./ipc";
import {
ConfigType,
Expand Down Expand Up @@ -228,6 +228,11 @@ const api: Sandbox = {
reloadApp: async ({ isMultiEngineOffMode }) => {
await ipcRendererInvokeProxy.RELOAD_APP({ isMultiEngineOffMode });
},

/** webUtils.getPathForFileを呼ぶ */
getPathForFile: (file) => {
return webUtils.getPathForFile(file);
},
};

contextBridge.exposeInMainWorld(SandboxKey, api);
1 change: 1 addition & 0 deletions src/components/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,7 @@ onMounted(async () => {
// プロジェクトファイルが指定されていればロード
if (typeof projectFilePath === "string" && projectFilePath !== "") {
isProjectFileLoaded.value = await store.actions.LOAD_PROJECT_FILE({
type: "path",
filePath: projectFilePath,
});
} else {
Expand Down
3 changes: 2 additions & 1 deletion src/components/Menu/MenuBar/MenuBar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ const saveProjectAs = async () => {
const importProject = () => {
if (!uiLocked.value) {
void store.actions.LOAD_PROJECT_FILE({});
void store.actions.LOAD_PROJECT_FILE({ type: "dialog" });
}
};
Expand Down Expand Up @@ -198,6 +198,7 @@ const updateRecentProjects = async () => {
label: projectFilePath,
onClick: () => {
void store.actions.LOAD_PROJECT_FILE({
type: "path",
filePath: projectFilePath,
});
},
Expand Down
19 changes: 17 additions & 2 deletions src/components/Talk/TalkEditor.vue
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ import {
actionPostfixSelectNthCharacter,
HotkeyActionNameType,
} from "@/domain/hotkeyAction";
import { isElectron } from "@/helpers/platform";
const props = defineProps<{
isEnginesReady: boolean;
Expand Down Expand Up @@ -574,13 +575,27 @@ const dragEventCounter = ref(0);
const loadDraggedFile = (event: { dataTransfer: DataTransfer | null }) => {
if (!event.dataTransfer || event.dataTransfer.files.length === 0) return;
const file = event.dataTransfer.files[0];
// electronの場合のみファイルパスを取得できる
const filePath = isElectron ? window.backend.getPathForFile(file) : undefined;
switch (path.extname(file.name)) {
case ".txt":
void store.actions.COMMAND_IMPORT_FROM_FILE({ filePath: file.path });
if (filePath) {
void store.actions.COMMAND_IMPORT_FROM_FILE({ type: "path", filePath });
} else {
void store.actions.COMMAND_IMPORT_FROM_FILE({ type: "file", file });
}
break;
case ".vvproj":
void store.actions.LOAD_PROJECT_FILE({ filePath: file.path });
if (filePath) {
void store.actions.LOAD_PROJECT_FILE({ type: "path", filePath });
} else {
void store.actions.LOAD_PROJECT_FILE({ type: "file", file });
}
break;
default:
void store.actions.SHOW_ALERT_DIALOG({
title: "対応していないファイルです",
Expand Down
2 changes: 1 addition & 1 deletion src/components/Talk/ToolBar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ const saveProject = async () => {
await store.actions.SAVE_PROJECT_FILE({ overwrite: true });
};
const importTextFile = () => {
void store.actions.COMMAND_IMPORT_FROM_FILE({});
void store.actions.COMMAND_IMPORT_FROM_FILE({ type: "dialog" });
};
const usableButtons: Record<
Expand Down
2 changes: 1 addition & 1 deletion src/components/Talk/menuBarData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ export const useMenuBarData = () => {
type: "button",
label: "テキスト読み込み",
onClick: () => {
void store.actions.COMMAND_IMPORT_FROM_FILE({});
void store.actions.COMMAND_IMPORT_FROM_FILE({ type: "dialog" });
},
disableWhenUiLocked: true,
},
Expand Down
7 changes: 5 additions & 2 deletions src/plugins/ipcMessageReceiverPlugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,11 @@ export const ipcMessageReceiver: Plugin = {
options: { store: Store<State, AllGetters, AllActions, AllMutations> },
) => {
window.backend.onReceivedIPCMsg({
LOAD_PROJECT_FILE: (_, { filePath } = {}) =>
void options.store.actions.LOAD_PROJECT_FILE({ filePath }),
LOAD_PROJECT_FILE: (_, { filePath }) =>
void options.store.actions.LOAD_PROJECT_FILE({
type: "path",
filePath,
}),

DETECT_MAXIMIZED: () => options.store.actions.DETECT_MAXIMIZED(),

Expand Down
34 changes: 23 additions & 11 deletions src/store/audio.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2886,24 +2886,36 @@ export const audioCommandStore = transformCommandStore(
prevAudioKey: undefined,
});
},
/**
* セリフテキストファイルを読み込む。
* ファイル選択ダイアログを表示するか、ファイルパス指定するか、Fileインスタンスを渡すか選べる。
*/
action: createUILockAction(
async (
{ state, mutations, actions, getters },
{ filePath }: { filePath?: string },
) => {
if (!filePath) {
async ({ state, mutations, actions, getters }, payload) => {
let filePath: undefined | string;
if (payload.type == "dialog") {
filePath = await window.backend.showImportFileDialog({
title: "セリフ読み込み",
});
if (!filePath) return;
} else if (payload.type == "path") {
filePath = payload.filePath;
}
let body = new TextDecoder("utf-8").decode(
await window.backend.readFile({ filePath }).then(getValueOrThrow),
);

let buf: ArrayBuffer;
if (filePath != undefined) {
buf = await window.backend
.readFile({ filePath })
.then(getValueOrThrow);
} else {
if (payload.type != "file")
throw new UnreachableError("payload.type != 'file'");
buf = await payload.file.arrayBuffer();
}

let body = new TextDecoder("utf-8").decode(buf);
if (body.includes("\ufffd")) {
body = new TextDecoder("shift-jis").decode(
await window.backend.readFile({ filePath }).then(getValueOrThrow),
);
body = new TextDecoder("shift-jis").decode(buf);
}
const audioItems: AudioItem[] = [];
let baseAudioItem: AudioItem | undefined = undefined;
Expand Down
34 changes: 20 additions & 14 deletions src/store/project.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import {
DEFAULT_TPQN,
} from "@/sing/domain";
import { EditorType } from "@/type/preload";
import { IsEqual } from "@/type/utility";
import { IsEqual, UnreachableError } from "@/type/utility";
import {
showAlertDialog,
showMessageDialog,
Expand Down Expand Up @@ -166,33 +166,39 @@ export const projectStore = createPartialStore<ProjectStoreTypes>({
LOAD_PROJECT_FILE: {
/**
* プロジェクトファイルを読み込む。読み込めたかの成否が返る。
* ファイル選択ダイアログを表示するか、ファイルパス指定するか、Fileインスタンスを渡すか選べる。
* エラー発生時はダイアログが表示される。
*/
action: createUILockAction(
async (
{ actions, mutations, getters },
{ filePath }: { filePath?: string },
) => {
if (!filePath) {
// Select and load a project File.
async ({ actions, mutations, getters }, payload) => {
let filePath: undefined | string;
if (payload.type == "dialog") {
const ret = await window.backend.showProjectLoadDialog({
title: "プロジェクトファイルの選択",
});
if (ret == undefined || ret?.length == 0) {
return false;
}
filePath = ret[0];
} else if (payload.type == "path") {
filePath = payload.filePath;
}

let buf: ArrayBuffer;
try {
buf = await window.backend
.readFile({ filePath })
.then(getValueOrThrow);
let buf: ArrayBuffer;
if (filePath != undefined) {
buf = await window.backend
.readFile({ filePath })
.then(getValueOrThrow);

await actions.APPEND_RECENTLY_USED_PROJECT({
filePath,
});
await actions.APPEND_RECENTLY_USED_PROJECT({
filePath,
});
} else {
if (payload.type != "file")
throw new UnreachableError("payload.type != 'file'");
buf = await payload.file.arrayBuffer();
}

const text = new TextDecoder("utf-8").decode(buf).trim();
const parsedProjectData = await actions.PARSE_PROJECT_FILE({
Expand Down
14 changes: 12 additions & 2 deletions src/store/type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -690,7 +690,12 @@ export type AudioCommandStoreTypes = {
mutation: {
audioKeyItemPairs: { audioItem: AudioItem; audioKey: AudioKey }[];
};
action(payload: { filePath?: string }): void;
action(
payload:
| { type: "dialog" }
| { type: "path"; filePath: string }
| { type: "file"; file: File },
): void;
};

COMMAND_PUT_TEXTS: {
Expand Down Expand Up @@ -1837,7 +1842,12 @@ export type ProjectStoreTypes = {
};

LOAD_PROJECT_FILE: {
action(payload: { filePath?: string }): boolean;
action(
payload:
| { type: "dialog" }
| { type: "path"; filePath: string }
| { type: "file"; file: File },
): boolean;
};

SAVE_PROJECT_FILE: {
Expand Down
2 changes: 1 addition & 1 deletion src/type/ipc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ export type IpcIHData = {
*/
export type IpcSOData = {
LOAD_PROJECT_FILE: {
args: [obj: { filePath?: string }];
args: [obj: { filePath: string }];
return: void;
};

Expand Down
1 change: 1 addition & 0 deletions src/type/preload.ts
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ export interface Sandbox {
uninstallVvppEngine(engineId: EngineId): Promise<boolean>;
validateEngineDir(engineDir: string): Promise<EngineDirValidationResult>;
reloadApp(obj: { isMultiEngineOffMode?: boolean }): Promise<void>;
getPathForFile(file: File): string;
}

export type AppInfos = {
Expand Down

0 comments on commit df4ad34

Please sign in to comment.