Skip to content

Commit 06c2920

Browse files
linxiaodongbuxuku
authored andcommitted
feat: drop
1 parent f2c5514 commit 06c2920

File tree

6 files changed

+85
-3
lines changed

6 files changed

+85
-3
lines changed

main/background.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@ if (isProd) {
3434
},
3535
});
3636

37+
mainWindow.webContents.on('will-navigate', (e) => {
38+
e.preventDefault();
39+
});
40+
3741
if (isProd) {
3842
await mainWindow.loadURL(`app://./${userLanguage}/home/`);
3943
} else {

main/helpers/ipcHandler.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { ipcMain, BrowserWindow, dialog, shell } from 'electron';
2+
import * as fs from 'fs';
23

34
export function setupIpcHandlers(mainWindow: BrowserWindow) {
45
ipcMain.on("message", async (event, arg) => {
@@ -36,4 +37,20 @@ export function setupIpcHandlers(mainWindow: BrowserWindow) {
3637
ipcMain.on("openUrl", (event, url) => {
3738
shell.openExternal(url);
3839
});
40+
41+
ipcMain.handle('getDroppedFiles', async (event, files) => {
42+
// 验证文件是否存在和可访问
43+
const validPaths = await Promise.all(
44+
files.map(async (filePath) => {
45+
try {
46+
await fs.promises.access(filePath);
47+
return filePath;
48+
} catch {
49+
return null;
50+
}
51+
})
52+
);
53+
54+
return validPaths.filter(Boolean);
55+
});
3956
}

main/helpers/whisper.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ export const install = (event, source) => {
6262
url: repoUrl,
6363
singleBranch: true,
6464
depth: 1,
65+
ref: 'v1.7.2',
6566
onProgress: (res) => {
6667
if (res.total) {
6768
event.sender.send("installWhisperProgress", res.phase, res.loaded / res.total);

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"private": true,
33
"name": "video-subtitle-master",
44
"description": "视频转字幕,字幕翻译软件",
5-
"version": "1.3.0",
5+
"version": "1.4.0",
66
"author": "buxuku <[email protected]>",
77
"main": "app/background.js",
88
"scripts": {

renderer/lib/utils.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,3 +147,24 @@ export const getModelDownloadUrl = (modelName: string, source: 'hf-mirror' | 'hu
147147
const domain = source === 'hf-mirror' ? 'hf-mirror.com' : 'huggingface.co';
148148
return `https://${domain}/ggerganov/whisper.cpp/resolve/main/ggml-${modelName.toLowerCase()}.bin?download=true`;
149149
};
150+
151+
// 添加支持的文件扩展名常量
152+
export const SUPPORTED_FILE_EXTENSIONS = [
153+
// 视频格式
154+
'mp4', 'avi', 'mov', 'mkv', 'flv', 'wmv', 'webm',
155+
// 音频格式
156+
'mp3', 'wav', 'ogg', 'aac', 'wma', 'flac', 'm4a',
157+
'aiff', 'ape', 'opus', 'ac3', 'amr', 'au', 'mid',
158+
// 其他常见格式
159+
'3gp', 'asf', 'rm', 'rmvb', 'vob', 'ts', 'mts', 'm2ts',
160+
// 字幕格式
161+
'srt', 'vtt', 'ass', 'ssa'
162+
] as const;
163+
164+
// 添加文件过滤方法
165+
export const filterSupportedFiles = (files: File[]) => {
166+
return Array.from(files).filter(file => {
167+
const ext = file.name.toLowerCase().split('.').pop();
168+
return SUPPORTED_FILE_EXTENSIONS.includes(ext as typeof SUPPORTED_FILE_EXTENSIONS[number]);
169+
});
170+
};

renderer/pages/[locale]/home.tsx

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import React, { useEffect, useState } from 'react';
2-
2+
import { cn } from "lib/utils";
33

44
import { ScrollArea } from '@/components/ui/scroll-area';
55

@@ -13,6 +13,7 @@ import TaskList from '@/components/TaskList';
1313
import TaskConfigForm from '@/components/TaskConfigForm';
1414
import TaskListControl from '@/components/TaskListControl';
1515
import { getStaticPaths, makeStaticProperties } from '../../lib/get-static'
16+
import { filterSupportedFiles } from 'lib/utils';
1617

1718

1819

@@ -37,6 +38,36 @@ export default function Component() {
3738
window.ipc.send('setTasks', files);
3839
}, [files]);
3940

41+
const [isDragging, setIsDragging] = useState(false);
42+
43+
const handleDragOver = (e: React.DragEvent) => {
44+
e.preventDefault();
45+
setIsDragging(true);
46+
};
47+
48+
const handleDragLeave = (e: React.DragEvent) => {
49+
e.preventDefault();
50+
setIsDragging(false);
51+
};
52+
53+
const handleDrop = (e: React.DragEvent) => {
54+
e.preventDefault();
55+
setIsDragging(false);
56+
57+
const droppedFiles = filterSupportedFiles(Array.from(e.dataTransfer.files));
58+
59+
if (droppedFiles.length > 0) {
60+
const fileList = droppedFiles.map(file => file.path);
61+
window?.ipc?.invoke('getDroppedFiles', fileList).then((filePaths) => {
62+
const newFiles = filePaths.map(filePath => ({
63+
uuid: Math.random().toString(36).substring(2),
64+
filePath
65+
}));
66+
setFiles(prevFiles => [...prevFiles, ...newFiles]);
67+
});
68+
}
69+
};
70+
4071
return (
4172
<div className="grid flex-1 gap-4 overflow-auto p-4 md:grid-cols-2 lg:grid-cols-3">
4273
<div className="relative hidden flex-col items-start gap-8 md:flex">
@@ -48,7 +79,15 @@ export default function Component() {
4879
isInstalledModel={isInstalledModel}
4980
/>
5081
</div>
51-
<div className="relative flex h-full min-h-[50vh] border flex-col rounded-xl p-4 lg:col-span-2">
82+
<div
83+
className={cn(
84+
"relative flex h-full min-h-[50vh] border flex-col rounded-xl p-4 lg:col-span-2",
85+
isDragging && "border-2 border-dashed border-primary bg-muted/50"
86+
)}
87+
onDrop={handleDrop}
88+
onDragOver={handleDragOver}
89+
onDragLeave={handleDragLeave}
90+
>
5291
<TaskListControl setFiles={setFiles} />
5392
<ScrollArea className="max-h-[780px]">
5493
<TaskList files={files} formData={formData} />

0 commit comments

Comments
 (0)