Skip to content

Commit

Permalink
Refactor app
Browse files Browse the repository at this point in the history
  • Loading branch information
Thavarshan committed Aug 17, 2024
1 parent 3a83c06 commit ffd503d
Show file tree
Hide file tree
Showing 16 changed files with 291 additions and 137 deletions.
2 changes: 1 addition & 1 deletion .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ root = true
[{*.html,*.js,*.json,*.md,*.ts,*.yml,*eslintrc}]
indent_style = space
indent_size = 2
insert_final_newline = true
insert_final_newline = false
max_line_length = 160
trim_trailing_whitespace = true

Expand Down
8 changes: 7 additions & 1 deletion .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,13 @@
{
"SwitchCase": 1
}
]
],
"max-len": [
"error",
{
"code": 80
}
],
},
"ignorePatterns": [
"*.test.ts"
Expand Down
7 changes: 7 additions & 0 deletions forge.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,13 @@ const config: ForgeConfig = {
unpack: '**/node_modules/ffmpeg-static/ffmpeg',
},
icon: 'src/assets/images/icon/icon',
extraResource: 'node_modules/ffmpeg-static/ffmpeg',
osxSign: {},
osxNotarize: {
appleId: process.env.APPLE_ID,
appleIdPassword: process.env.APPLE_ID_PASSWORD,
teamId: process.env.TEAM_ID,
},
},
rebuildConfig: {},
makers: [
Expand Down
32 changes: 16 additions & 16 deletions src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ import {
TrashIcon,
ReloadIcon,
} from '@radix-icons/vue';
import { Channel } from './enums/channel';
import { SUPPORTED_FORMATS } from './consts/formats';
const files = ref<File[] | undefined>();
const saveDirectory = ref<string | undefined>();
Expand All @@ -35,18 +37,20 @@ onMounted(async () => {
saveDirectory.value = await window.electron.getDownloadsPath();
// Listen for backend messages
window.electron.on('ffmpeg-status', (_event: any, message: string) => {
window.electron.on(Channel.FFMPEG_STATUS, (_event: any, message: string) => {
toast({
title: 'FFmpeg Status',
description: message,
});
});
window.electron.on('conversion-progress', (_event: any, { filePath, progress }: { filePath: string, progress: number; }) => {
window.electron.on(Channel.CONVERSION_PROGRESS, (
_event: any, { filePath, progress }: { filePath: string, progress: number; }
) => {
conversionProgress.value[filePath] = progress;
});
window.electron.on('conversion-error', (_event: any, error: string) => {
window.electron.on(Channel.CONVERSION_ERROR, (_event: any, error: string) => {
converting.value = false;
toast({
title: 'Error',
Expand All @@ -58,21 +62,13 @@ onMounted(async () => {
onUnmounted(() => {
// Cleanup IPC listeners to avoid memory leaks
window.electron.removeAllListeners('ffmpeg-status');
window.electron.removeAllListeners('conversion-progress');
window.electron.removeAllListeners('conversion-error');
window.electron.removeAllListeners(Channel.FFMPEG_STATUS);
window.electron.removeAllListeners(Channel.CONVERSION_PROGRESS);
window.electron.removeAllListeners(Channel.CONVERSION_ERROR);
});
const emit = defineEmits(['files-uploaded']);
const CONVERSION_FORMATS = [
'mp4', 'webm', 'ogg', 'flv', 'avi',
'mov', 'wmv', '3gp', 'mkv', 'm4v',
'mpg', 'mpeg', 'vob', 'ts', 'asf',
'f4v', 'h264', 'hevc', 'm2ts', 'm2v',
'mts', 'ogv', 'rm', 'swf', 'xvid',
];
function handleUpload(uploads: FileList) {
files.value = Array.from(uploads);
}
Expand Down Expand Up @@ -116,7 +112,11 @@ async function convertFiles() {
const outputFormat = convertTo.value;
const outputDirectory = saveDirectory.value;
const outputFilePath = await window.electron.convertVideo(filePath, outputFormat, outputDirectory);
const outputFilePath = await window.electron.convertVideo(
filePath,
outputFormat,
outputDirectory
);
toast({
title: 'File converted',
Expand Down Expand Up @@ -207,7 +207,7 @@ async function convertFiles() {
<div class="h-56 overflow-hidden">
<div class="mt-4 h-56 overflow-y-auto">
<ul role="list" class="grid grid-cols-3 gap-4">
<li v-for="format in CONVERSION_FORMATS" :key="format" class="flex items-center gap-2">
<li v-for="format in SUPPORTED_FORMATS" :key="format" class="flex items-center gap-2">
<button
type="button"
class="flex items-center justify-center p-2 rounded-lg flex-1"
Expand Down
25 changes: 25 additions & 0 deletions src/config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import path from 'path';
import { AppConfig } from './interfaces/app-config';

const isDev: boolean = process.env.NODE_ENV === 'development';

export const config = {
appName: 'Comet',
productName: 'comet',
title: 'Comet | Video Converter',
appId: 'com.github.comet',
icons: path.join(__dirname, 'assets', 'images', 'icon', 'icon.png'),
isDev,
directories: {
output: 'out',
},
width: isDev ? 1200 : 700,
height: 600,
resizable: false,
show: false,
webPreferences: {
preload: path.join(__dirname, 'preload.js'),
nodeIntegration: false,
contextIsolation: true,
}
} as AppConfig;
7 changes: 7 additions & 0 deletions src/consts/formats.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export const SUPPORTED_FORMATS = [
'mp4', 'webm', 'ogg', 'flv', 'avi',
'mov', 'wmv', '3gp', 'mkv', 'm4v',
'mpg', 'mpeg', 'vob', 'ts', 'asf',
'f4v', 'h264', 'hevc', 'm2ts', 'm2v',
'mts', 'ogv', 'rm', 'swf', 'xvid',
];
8 changes: 8 additions & 0 deletions src/enums/channel.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export enum Channel {
CONVERSION_PROGRESS = 'conversion-progress',
CONVERSION_ERROR = 'conversion-error',
DIALOG_SELECT_DIRECTORY = 'dialog:selectDirectory',
GET_DOWNLOADS_PATH = 'getDownloadsPath',
CONVERT_VIDEO = 'convertVideo',
FFMPEG_STATUS = 'ffmpeg-status',
}
11 changes: 11 additions & 0 deletions src/enums/event.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
export enum Event {
READY = 'ready',
WINDOW_ALL_CLOSED = 'window-all-closed',
ACTIVATE = 'activate',
DIALOG_SELECT_DIRECTORY = 'dialog:selectDirectory',
PRROGRESS = 'progress',
END = 'end',
ERROR = 'error',
UNCAUGHT_EXCEPTION = 'uncaughtException',
READY_TO_SHOW = 'ready-to-show',
}
5 changes: 5 additions & 0 deletions src/enums/platform.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export enum Platform {
WINDOWS = 'win32',
MAC = 'darwin',
LINUX = 'linux',
}
5 changes: 5 additions & 0 deletions src/enums/shortcut.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export enum ShortCut {
RELOAD = 'CmdOrCtrl+R',
RELOAD_F5 = 'F5',
TOGGLE_DEV_TOOLS = 'CmdOrCtrl+Shift+I',
}
9 changes: 9 additions & 0 deletions src/interfaces/app-config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { BrowserWindowConstructorOptions } from 'electron';

export interface AppConfig extends BrowserWindowConstructorOptions {
appName: string,
productName: string,
title: string,
appId: string,
isDev: boolean,
};
37 changes: 37 additions & 0 deletions src/lib/conversion-handler.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { IpcMainInvokeEvent } from 'electron';
import { FfmpegCommand } from 'fluent-ffmpeg';
import { Channel } from '../enums/channel';
import { Event } from '../enums/event';

/**
* Handle the video conversion process.
*/
export async function handleConversion(
ffmpeg: (filePath: string) => FfmpegCommand,
event: IpcMainInvokeEvent,
filePath: string,
outputFilePath: string,
outputFormat: string
): Promise<string> {
return new Promise((resolve, reject) => {
ffmpeg(filePath)
.toFormat(outputFormat)
.on(Event.PRROGRESS, (progress) => {
if (progress.percent) {
event.sender.send(
Channel.CONVERSION_PROGRESS,
progress
);
}
})
.on(Event.END, () => resolve(outputFilePath))
.on(Event.ERROR, (error) => {
event.sender.send(
Channel.CONVERSION_ERROR,
`FFmpeg error: ${error.message}`
);
reject(error);
})
.save(outputFilePath);
});
}
59 changes: 59 additions & 0 deletions src/lib/ffmpeg.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import fs from 'fs';
import { execSync } from 'child_process';
import ffmpeg from 'fluent-ffmpeg';
import { App, IpcMain, Dialog } from 'electron';

/**
* Get the path to the FFmpeg binary.
*
* @throws {Error} Will throw an error if the FFmpeg binary is not found.
*/
export function getFfmpegPath(ipcMain: IpcMain): string {
let ffmpegStatic: string | undefined;

try {
const ffmpegPath = execSync('which ffmpeg').toString().trim();

if (fs.existsSync(ffmpegPath)) {
return ffmpegPath;
}
} catch (error) {
ipcMain.emit('ffmpeg-status', 'System FFmpeg not found, using ffmpeg-static');
}

if (typeof process !== 'undefined' && process.versions && process.versions.node) {
ffmpegStatic = require('ffmpeg-static');
}

if (ffmpegStatic) {
return ffmpegStatic;
}

throw new Error('FFmpeg binary not found');
}

/**
* Create a FFmpeg command instance.
*/
export function makeFfmpeg(
app: App,
ipcMain: IpcMain,
dialog: Dialog
): (filePath: string) => ffmpeg.FfmpegCommand {
const ffmpegPath = getFfmpegPath(ipcMain);

if (ffmpegPath) {
try {
fs.chmodSync(ffmpegPath, 0o755);
ffmpeg.setFfmpegPath(ffmpegPath);
} catch (err) {
dialog.showErrorBox('FFmpeg Error', `Failed to set executable permissions or FFmpeg path: ${err.message}`);
app.quit();
}
} else {
dialog.showErrorBox('FFmpeg Error', 'FFmpeg binary not found');
app.quit();
}

return (filePath: string) => ffmpeg(filePath);
}
45 changes: 45 additions & 0 deletions src/lib/window-manager.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import {
BrowserWindow,
globalShortcut,
} from 'electron';
import path from 'path';
import { config } from '../config';
import { ShortCut } from '../enums/shortcut';
import { Event } from '../enums/event';

/**
* The main application window.
*/
let mainWindow: BrowserWindow | undefined = undefined;

/**
* Create the main application window.
*/
export function createWindow(): BrowserWindow {
mainWindow = new BrowserWindow({ ...config });

mainWindow.once(Event.READY_TO_SHOW, () => mainWindow.show());

const mainWindowUrl: string = config.isDev
? process.env.MAIN_WINDOW_VITE_DEV_SERVER_URL || 'default_dev_url'
: `file://${path.join(__dirname, '../renderer', process.env.MAIN_WINDOW_VITE_NAME || 'default_name', 'index.html')}`;

mainWindow.loadURL(mainWindowUrl);

if (config.isDev) {
mainWindow.webContents.openDevTools();
}

if (!config.isDev) {
// eslint-disable-next-line @typescript-eslint/no-empty-function
globalShortcut.register(ShortCut.RELOAD, () => { });
// eslint-disable-next-line @typescript-eslint/no-empty-function
globalShortcut.register(ShortCut.RELOAD_F5, () => { });
}

return mainWindow;
}

export {
mainWindow,
};
Loading

0 comments on commit ffd503d

Please sign in to comment.