227 lines
6.7 KiB
TypeScript
227 lines
6.7 KiB
TypeScript
import { ipcMain, shell, IpcMainEvent, dialog } from 'electron'
|
|
import Constants from './utils/Constants'
|
|
import { join, dirname } from 'path'
|
|
import {
|
|
writeFileSync,
|
|
readFileSync,
|
|
existsSync,
|
|
ensureDirSync,
|
|
copyFileSync
|
|
} from 'fs-extra'
|
|
|
|
/*
|
|
* IPC Communications
|
|
* */
|
|
export default class IPCs {
|
|
static initialize(): void {
|
|
// Get application version
|
|
ipcMain.handle('msgRequestGetVersion', () => {
|
|
return Constants.APP_VERSION
|
|
})
|
|
|
|
// Open url via web browser
|
|
ipcMain.on(
|
|
'msgOpenExternalLink',
|
|
async (event: IpcMainEvent, url: string) => {
|
|
await shell.openExternal(url)
|
|
}
|
|
)
|
|
|
|
// Open file
|
|
ipcMain.handle(
|
|
'msgOpenFile',
|
|
async (event: IpcMainEvent, filter: string) => {
|
|
const filters = []
|
|
if (filter === 'text') {
|
|
filters.push({ name: 'Text', extensions: ['txt', 'json'] })
|
|
} else if (filter === 'zip') {
|
|
filters.push({ name: 'Zip', extensions: ['zip'] })
|
|
} else if (filter === 'any') {
|
|
filters.push({ name: 'All Files', extensions: ['*'] })
|
|
}
|
|
const dialogResult = await dialog.showOpenDialog({
|
|
properties: ['openFile'],
|
|
filters
|
|
})
|
|
return dialogResult
|
|
}
|
|
)
|
|
|
|
// Select directory
|
|
ipcMain.handle('msgSelectDirectory', async () => {
|
|
const dialogResult = await dialog.showOpenDialog({
|
|
properties: ['openDirectory']
|
|
})
|
|
|
|
if (!dialogResult.canceled && dialogResult.filePaths.length > 0) {
|
|
return {
|
|
canceled: false,
|
|
filePath: dialogResult.filePaths[0]
|
|
}
|
|
}
|
|
|
|
return { canceled: true }
|
|
})
|
|
|
|
// Find all files in a folder recursively
|
|
ipcMain.handle(
|
|
'msgFindFilesInFolder',
|
|
async (event: IpcMainEvent, folderPath: string) => {
|
|
try {
|
|
const { readdirSync, statSync } = require('fs')
|
|
const { join } = require('path')
|
|
|
|
const foundFiles: string[] = []
|
|
|
|
const searchFiles = (dir: string) => {
|
|
const items = readdirSync(dir)
|
|
|
|
for (const item of items) {
|
|
const fullPath = join(dir, item)
|
|
const stats = statSync(fullPath)
|
|
|
|
if (stats.isDirectory()) {
|
|
// Recursively search in subdirectories
|
|
searchFiles(fullPath)
|
|
} else if (stats.isFile()) {
|
|
// Add file to the list
|
|
foundFiles.push(fullPath)
|
|
}
|
|
}
|
|
}
|
|
|
|
searchFiles(folderPath)
|
|
|
|
return foundFiles
|
|
} catch (error) {
|
|
console.error('Error finding files in folder:', error)
|
|
return []
|
|
}
|
|
}
|
|
)
|
|
|
|
// Load data from local file
|
|
ipcMain.handle(
|
|
'msgLoadData',
|
|
async (event: IpcMainEvent, fileName: string) => {
|
|
try {
|
|
const userDataPath = join(Constants.APP_DATA_PATH, 'data')
|
|
const filePath = join(userDataPath, fileName)
|
|
|
|
// Ensure directory exists
|
|
ensureDirSync(userDataPath)
|
|
|
|
if (existsSync(filePath)) {
|
|
const data = readFileSync(filePath, 'utf-8')
|
|
return data
|
|
}
|
|
return null
|
|
} catch (error) {
|
|
console.error('Error loading data:', error)
|
|
return null
|
|
}
|
|
}
|
|
)
|
|
|
|
// Save data to local file
|
|
ipcMain.handle(
|
|
'msgSaveData',
|
|
async (event: IpcMainEvent, fileName: string, data: string) => {
|
|
try {
|
|
const userDataPath = join(Constants.APP_DATA_PATH, 'data')
|
|
const filePath = join(userDataPath, fileName)
|
|
|
|
// Ensure directory exists
|
|
ensureDirSync(userDataPath)
|
|
|
|
writeFileSync(filePath, data, 'utf-8')
|
|
return true
|
|
} catch (error) {
|
|
console.error('Error saving data:', error)
|
|
return false
|
|
}
|
|
}
|
|
)
|
|
|
|
// Execute template
|
|
ipcMain.handle(
|
|
'msgExecuteTemplate',
|
|
async (
|
|
event: IpcMainEvent,
|
|
templateId: string,
|
|
targetPath: string,
|
|
baseDirNames: string[]
|
|
) => {
|
|
try {
|
|
// Load templates data
|
|
const userDataPath = join(Constants.APP_DATA_PATH, 'data')
|
|
const filePath = join(userDataPath, 'templates.json')
|
|
|
|
let templates = []
|
|
if (existsSync(filePath)) {
|
|
const templatesData = readFileSync(filePath, 'utf-8')
|
|
templates = JSON.parse(templatesData)
|
|
}
|
|
|
|
const template = templates.find((t) => t.id === templateId)
|
|
|
|
if (!template) {
|
|
return { success: false, error: 'Template not found' }
|
|
}
|
|
|
|
// Create directories and files for each base directory name
|
|
for (const baseDirName of baseDirNames) {
|
|
if (!baseDirName.trim()) continue
|
|
|
|
// Create base directory
|
|
const baseDirPath = join(targetPath, baseDirName)
|
|
ensureDirSync(baseDirPath)
|
|
|
|
// Helper function to traverse the tree and collect all nodes
|
|
const collectAllNodes = (nodes, allNodes = []) => {
|
|
for (const node of nodes) {
|
|
allNodes.push(node);
|
|
if (node.children) {
|
|
collectAllNodes(node.children, allNodes);
|
|
}
|
|
}
|
|
return allNodes;
|
|
};
|
|
|
|
// Collect all nodes from the tree structure
|
|
if (template.treeStructure && template.treeStructure.length > 0) {
|
|
const allNodes = collectAllNodes(template.treeStructure);
|
|
|
|
// Process all nodes, making sure directories are created before files
|
|
for (const node of allNodes) {
|
|
const nodePath = join(baseDirPath, node.path);
|
|
|
|
if (node.type === 'directory') {
|
|
ensureDirSync(nodePath);
|
|
} else if (node.type === 'file') {
|
|
const fileDir = dirname(nodePath);
|
|
ensureDirSync(fileDir);
|
|
|
|
if (node.sourceFilePath) {
|
|
// Copy from source file
|
|
const sourceContent = readFileSync(node.sourceFilePath);
|
|
writeFileSync(nodePath, sourceContent);
|
|
} else if (node.content) {
|
|
// Write content directly
|
|
writeFileSync(nodePath, node.content, 'utf-8');
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return { success: true }
|
|
} catch (error) {
|
|
console.error('Error executing template:', error)
|
|
return { success: false, error: error.message }
|
|
}
|
|
}
|
|
)
|
|
}
|
|
}
|