mirror of
https://github.com/damp11113-software/ccIDE.git
synced 2025-04-27 06:28:14 +00:00
641 lines
23 KiB
JavaScript
641 lines
23 KiB
JavaScript
console.log("Initializing...")
|
|
const { app, BrowserWindow, ipcMain, Menu, dialog } = require('electron')
|
|
const fs = require('fs');
|
|
const prompt = require('electron-prompt');
|
|
const path = require('path');
|
|
const pino = require('pino')
|
|
const pretty = require('pino-pretty');
|
|
const https = require('node:https');
|
|
|
|
const ipc = ipcMain
|
|
|
|
const logger = pino(pretty())
|
|
|
|
process.env['ELECTRON_DISABLE_SECURITY_WARNINGS'] = 'true';
|
|
|
|
var ena_splash = process.env['CCIDE_ENABLE_MAIN_SPLASH'] == 'true';
|
|
|
|
var currentprojectpath = null;
|
|
var currentprojectname = null;
|
|
var currentprojectopen = false;
|
|
var appexiting = false;
|
|
var appreloading = false;
|
|
var currentworkspacechange = false;
|
|
var isopennewproject = false;
|
|
|
|
var appstarted = false;
|
|
var version;
|
|
var gitver;
|
|
|
|
try {
|
|
// Read package.json synchronously
|
|
const data = fs.readFileSync('package.json', 'utf8');
|
|
|
|
// Parse JSON
|
|
const packageJson = JSON.parse(data);
|
|
|
|
// Get project version
|
|
version = packageJson.version;
|
|
} catch (err) {
|
|
console.error("Error reading package.json:", err);
|
|
}
|
|
|
|
function checkupdate() {
|
|
return new Promise((resolve, reject) => {
|
|
const req = https.request({
|
|
hostname: 'api.github.com',
|
|
port: 443,
|
|
path: '/repos/DPSoftware-Foundation/ccIDE/releases/latest',
|
|
method: 'GET',
|
|
headers: {
|
|
'User-Agent': 'ccIDE-Check-Update-Service', // GitHub API requires a User-Agent header
|
|
}
|
|
}, (res) => {
|
|
let data = '';
|
|
res.setEncoding('utf8');
|
|
res.on('data', (chunk) => {
|
|
data += chunk;
|
|
});
|
|
res.on('end', () => {
|
|
try {
|
|
const json = JSON.parse(data);
|
|
resolve(json.tag_name); // Return the tag_name or other relevant data
|
|
} catch (e) {
|
|
reject('Error parsing JSON: ' + e.message);
|
|
}
|
|
});
|
|
});
|
|
|
|
req.on('error', (e) => {
|
|
reject('Error fetching release: ' + e.message);
|
|
});
|
|
|
|
req.end();
|
|
});
|
|
}
|
|
|
|
function normalizeVersion(version, length = 4) {
|
|
// Split the version string into parts and pad with zeros if necessary
|
|
return version.split('.').map(part => part.padStart(2, '0')).concat(Array(length).fill('00')).slice(0, length).join('.');
|
|
}
|
|
|
|
app.whenReady().then(async () => {
|
|
logger.info("Initializing splash window...")
|
|
reloadall(false);
|
|
var splash = new BrowserWindow({
|
|
width: 720,
|
|
height: 400,
|
|
icon: path.join(__dirname, 'assets', 'ccIDEIcon.ico'),
|
|
transparent: true,
|
|
frame: false,
|
|
center: true,
|
|
webPreferences: {
|
|
nodeIntegration: true,
|
|
contextIsolation: false,
|
|
},
|
|
resizable: false
|
|
});
|
|
|
|
splash.loadFile('src/splash.html');
|
|
|
|
while (!splash.isVisible()) {}
|
|
|
|
// checkupdate
|
|
logger.info("Checking for new update...")
|
|
splash.webContents.send("change-status", "Checking for new update...")
|
|
|
|
try {
|
|
const latestRelease = await checkupdate();
|
|
// Store the version or use it as needed
|
|
gitver = latestRelease;
|
|
} catch (error) {
|
|
logger.error('Error in update check:', error);
|
|
}
|
|
|
|
logger.info("Current version: " + version)
|
|
logger.info("Version in github: " + gitver)
|
|
|
|
|
|
const normalizedAppVersion = normalizeVersion(version);
|
|
|
|
if (!gitver) {
|
|
logger.error("Can't check update")
|
|
} else {
|
|
const normalizedReleaseVersion = normalizeVersion(gitver);
|
|
if (normalizedAppVersion >= normalizedReleaseVersion) {
|
|
logger.info("Software is up-to-date.");
|
|
} else {
|
|
logger.info("A new update is available: " + gitver)
|
|
var is_not_skip_update = localStorage.getItem('skip_update_version') != normalizedAppVersion;
|
|
var is_ignore = localStorage.getItem('ignore_update');
|
|
if (is_ignore || is_not_skip_update) {
|
|
const result = dialog.showMessageBoxSync({
|
|
type: 'question',
|
|
buttons: ['Update', 'Ignore', 'Skip'],
|
|
defaultId: 0,
|
|
title: 'Update Available',
|
|
message: `A new version (${gitver}) is available. Do you want to update now?`,
|
|
detail: 'Click "Update" to go to the release page, "Ignore" to ignore this update, or "Skip" to skip this version.'
|
|
});
|
|
switch (result.response) {
|
|
case 0: // 'Update'
|
|
(async () => {
|
|
try {
|
|
const { default: open } = await import('open');
|
|
|
|
await open('https://github.com/DPSoftware-Foundation/ccIDE/releases/latest');
|
|
console.log('URL opened in default browser');
|
|
} catch (err) {
|
|
console.error('Error opening URL:', err);
|
|
}
|
|
})();
|
|
break;
|
|
case 1: // 'Ignore'
|
|
localStorage.setItem('ignore_update', true);
|
|
break;
|
|
case 2: // 'Skip'
|
|
localStorage.setItem('skip_update_version', normalizedReleaseVersion);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
logger.info("Initializing main windows...")
|
|
splash.webContents.send("change-status", "Initializing main windows...")
|
|
|
|
const win = new BrowserWindow({
|
|
width: 1280,
|
|
height: 720,
|
|
icon: path.join(__dirname, 'assets', 'ccIDEIcon.ico'),
|
|
webPreferences: {
|
|
devTools: true,
|
|
nodeIntegration: true,
|
|
enableRemoteModule: true,
|
|
contextIsolation: false,
|
|
},
|
|
show: ena_splash,
|
|
center: true,
|
|
})
|
|
|
|
try {
|
|
win.loadFile('src/index.html');
|
|
} catch {
|
|
try {
|
|
win.loadFile('dist_src/index.html');
|
|
} catch {
|
|
dialog.showErrorBox("Error on startup", "Can't find index.html");
|
|
}
|
|
}
|
|
win.setTitle(`ccIDE v${version}`)
|
|
|
|
ipc.once('ready', () => {
|
|
splash.webContents.send("isloaded")
|
|
splash.webContents.send("change-status", "Thanks for using software from DPSoftware.")
|
|
splash.webContents.send("change-title", `ccIDE v${version}`)
|
|
logger.info("Ready!")
|
|
if (splash) {
|
|
splash.hide();
|
|
}
|
|
win.show();
|
|
//win.maximize();
|
|
appstarted = true;
|
|
});
|
|
|
|
ipc.on("splash-close", (event) => {
|
|
if (appstarted) {
|
|
splash.hide();
|
|
} else {
|
|
splash.close();
|
|
win.close();
|
|
}
|
|
})
|
|
|
|
ipc.on('erroronstart', (event, errormessage) => {
|
|
logger.error(errormessage)
|
|
dialog.showErrorBox("Error on startup", errormessage);
|
|
//win.openDevTools();
|
|
});
|
|
|
|
ipc.on('error', (event, errormessage) => {
|
|
logger.error(errormessage)
|
|
dialog.showErrorBox("Error", errormessage);
|
|
//win.openDevTools();
|
|
});
|
|
|
|
ipc.on('update-log-status', (event, status) => {
|
|
logger.info(status);
|
|
if (!appstarted) {
|
|
splash.webContents.send("change-status", status);
|
|
}
|
|
if (status == "Downloading blocks...") {
|
|
win.show();
|
|
}
|
|
});
|
|
|
|
//app.on('activate', () => {
|
|
// if (BrowserWindow.getAllWindows().length === 0) {
|
|
// createWindow()
|
|
// }
|
|
//})
|
|
|
|
function reloadall(isloaded=true) {
|
|
currentprojectpath = null;
|
|
currentprojectname = null;
|
|
currentprojectopen = false;
|
|
currentworkspacechange = false;
|
|
appexiting = false;
|
|
appreloading = false;
|
|
isopennewproject = false;
|
|
if (isloaded) {
|
|
win.setTitle(`ccIDE v${version}`)
|
|
win.reload();
|
|
}
|
|
}
|
|
|
|
logger.info("Settings up menu bar...")
|
|
// Define a custom menu template
|
|
const menuTemplate = [
|
|
{
|
|
label: 'File',
|
|
submenu: [
|
|
{
|
|
label: 'New',
|
|
accelerator: 'CmdOrCtrl+N',
|
|
click: () => {
|
|
if (currentworkspacechange) {
|
|
const result = dialog.showMessageBoxSync({
|
|
type: 'question',
|
|
buttons: ['Save', 'Don\'t Save', 'Cancel'],
|
|
defaultId: 2,
|
|
title: 'Save Changes',
|
|
message: "Your project is not saved",
|
|
});
|
|
if (result === 1) {
|
|
// Don't save
|
|
reloadall();
|
|
} else if (result === 0) {
|
|
// Save
|
|
appreloading = true;
|
|
win.webContents.send('save-workspace-request');
|
|
}
|
|
} else {
|
|
reloadall();
|
|
}
|
|
}
|
|
},
|
|
{
|
|
label: 'Open',
|
|
accelerator: 'CmdOrCtrl+O',
|
|
click: () => {
|
|
if (currentworkspacechange) {
|
|
const result = dialog.showMessageBoxSync({
|
|
type: 'question',
|
|
buttons: ['Save', 'Don\'t Save', 'Cancel'],
|
|
defaultId: 2,
|
|
title: 'Save Changes',
|
|
message: "Your project is not saved",
|
|
});
|
|
if (result === 1) {
|
|
// Don't save
|
|
dialog.showOpenDialog(win, {
|
|
title: 'Open Project',
|
|
defaultPath: app.getPath('documents'),
|
|
filters: [
|
|
{ name: 'ComputerCraft Project', extensions: ['ccp'] }
|
|
],
|
|
properties: ['openFile']
|
|
}).then(result => {
|
|
if (!result.canceled) {
|
|
const filePath = result.filePaths[0];
|
|
|
|
fs.readFile(filePath, 'utf8', (err, json) => {
|
|
if (err) {
|
|
console.error('Error loading workspace:', err);
|
|
return;
|
|
}
|
|
win.webContents.send('load-workspace', json);
|
|
|
|
currentprojectpath = result.filePaths[0]
|
|
currentprojectname = path.basename(result.filePaths[0]);
|
|
currentprojectopen = true;
|
|
|
|
win.setTitle(`${currentprojectname} | ccIDE v${version}`)
|
|
});
|
|
|
|
}
|
|
}).catch(err => {
|
|
console.error('Error showing open dialog:', err);
|
|
});
|
|
} else if (result === 0) {
|
|
// Save
|
|
isopennewproject = true;
|
|
win.webContents.send('save-workspace-request');
|
|
}
|
|
} else {
|
|
dialog.showOpenDialog(win, {
|
|
title: 'Open Project',
|
|
defaultPath: app.getPath('documents'),
|
|
filters: [
|
|
{ name: 'ComputerCraft Project', extensions: ['ccp'] }
|
|
],
|
|
properties: ['openFile']
|
|
}).then(result => {
|
|
if (!result.canceled) {
|
|
const filePath = result.filePaths[0];
|
|
|
|
fs.readFile(filePath, 'utf8', (err, json) => {
|
|
if (err) {
|
|
console.error('Error loading workspace:', err);
|
|
return;
|
|
}
|
|
win.webContents.send('load-workspace', json);
|
|
|
|
currentprojectpath = result.filePaths[0]
|
|
currentprojectname = path.basename(result.filePaths[0]);
|
|
currentprojectopen = true;
|
|
|
|
win.setTitle(`${currentprojectname} | ccIDE v${version}`)
|
|
});
|
|
|
|
}
|
|
}).catch(err => {
|
|
console.error('Error showing open dialog:', err);
|
|
});
|
|
}
|
|
}
|
|
},
|
|
{
|
|
label: 'Save',
|
|
accelerator: 'CmdOrCtrl+S',
|
|
click: () => {
|
|
win.webContents.send('save-workspace-request');
|
|
}
|
|
},
|
|
{
|
|
label: 'Save as',
|
|
accelerator: 'CmdOrCtrl+Shift+S',
|
|
click: () => {
|
|
currentprojectopen = false
|
|
win.webContents.send('save-workspace-request');
|
|
}
|
|
},
|
|
{ type: 'separator' },
|
|
{
|
|
label: 'Export',
|
|
submenu: [
|
|
{
|
|
label: "Export Lua",
|
|
accelerator: 'CmdOrCtrl+Shift+L',
|
|
click: () => {
|
|
win.webContents.send('export-lua-request');
|
|
}
|
|
}
|
|
]
|
|
},
|
|
{ type: 'separator' },
|
|
{
|
|
label: 'Exit',
|
|
accelerator: 'CmdOrCtrl+Q',
|
|
click: () => {
|
|
app.quit();
|
|
}
|
|
}
|
|
]
|
|
},
|
|
{
|
|
label: 'Edit',
|
|
submenu: [
|
|
{ label: "Undo", accelerator: "CmdOrCtrl+Z", selector: "undo:" },
|
|
{ label: "Redo", accelerator: "Shift+CmdOrCtrl+Z", selector: "redo:" },
|
|
{ type: "separator" },
|
|
{ label: "Cut", accelerator: "CmdOrCtrl+X", selector: "cut:" },
|
|
{ label: "Copy", accelerator: "CmdOrCtrl+C", selector: "copy:" },
|
|
{ label: "Paste", accelerator: "CmdOrCtrl+V", selector: "paste:" },
|
|
{ label: "Select All", accelerator: "CmdOrCtrl+A", selector: "selectAll:" }
|
|
]
|
|
},
|
|
{
|
|
label: 'Help',
|
|
submenu: [
|
|
{ label: 'DevTools', accelerator: 'F12', click: () => {win.openDevTools()}},
|
|
{ type: 'separator' },
|
|
{
|
|
label: 'About',
|
|
click: () => {
|
|
win.webContents.send("open-about")
|
|
}
|
|
},
|
|
{
|
|
label: 'Splash Screen',
|
|
click: () => {
|
|
if (!splash.isVisible()) {
|
|
splash.show();
|
|
} else {
|
|
splash.hide();
|
|
}
|
|
}
|
|
}
|
|
]
|
|
}
|
|
];
|
|
|
|
// Set the custom menu
|
|
const menu = Menu.buildFromTemplate(menuTemplate);
|
|
Menu.setApplicationMenu(menu);
|
|
|
|
logger.info("Settings up event...")
|
|
|
|
ipc.on('prompt', (event, promptText, defaultValue) => {
|
|
try {
|
|
prompt({
|
|
title: "ccIDE",
|
|
label: promptText,
|
|
value: defaultValue,
|
|
inputAttrs: {
|
|
type: 'text',
|
|
required: true
|
|
},
|
|
type: 'input',
|
|
alwaysOnTop: true
|
|
})
|
|
.then((r) => {
|
|
if(r === null) {
|
|
event.returnValue = null
|
|
} else {
|
|
event.returnValue = r
|
|
}
|
|
})
|
|
.catch(console.error);
|
|
} catch (error) {
|
|
console.error('Error showing prompt dialog:', error);
|
|
event.returnValue = null; // or handle error appropriately
|
|
}
|
|
});
|
|
|
|
ipc.on('save-workspace', (event, json) => {
|
|
if (!currentprojectopen) {
|
|
dialog.showSaveDialog(win, {
|
|
title: 'Save Project',
|
|
defaultPath: path.join(app.getPath('documents'), 'untitled.ccp'),
|
|
filters: [
|
|
{ name: 'ComputerCraft Project', extensions: ['ccp'] }
|
|
]
|
|
}).then(result => {
|
|
if (!result.canceled) {
|
|
fs.writeFile(result.filePath, JSON.stringify(json), (err) => {
|
|
if (err) {
|
|
console.error('Error saving project:', err);
|
|
dialog.showErrorBox("Save Project Error", err.message)
|
|
win.webContents.send('workspace-saved', false);
|
|
} else {
|
|
currentprojectpath = result.filePath
|
|
currentprojectname = path.basename(result.filePath);
|
|
currentprojectopen = true;
|
|
|
|
win.webContents.send('workspace-saved', true);
|
|
|
|
win.setTitle(`${currentprojectname} | ccIDE v${version}`)
|
|
if (currentworkspacechange) {
|
|
currentworkspacechange = false;
|
|
}
|
|
}
|
|
});
|
|
} else {
|
|
win.webContents.send('workspace-saved', false);
|
|
}
|
|
}).catch(err => {
|
|
console.error('Error showing save dialog:', err);
|
|
dialog.showErrorBox("Save Project Error", err.message)
|
|
win.webContents.send('workspace-saved', false);
|
|
});
|
|
} else {
|
|
fs.writeFile(currentprojectpath, JSON.stringify(json), (err) => {
|
|
if (err) {
|
|
console.error('Error saving project:', err);
|
|
dialog.showErrorBox("Save Project Error", err.message)
|
|
win.webContents.send('workspace-saved', false);
|
|
} else {
|
|
currentprojectopen = true;
|
|
|
|
win.webContents.send('workspace-saved', true);
|
|
|
|
win.setTitle(`${currentprojectname} | ccIDE v${version}`)
|
|
|
|
if (currentworkspacechange) {
|
|
currentworkspacechange = false;
|
|
}
|
|
|
|
if (appexiting) {
|
|
app.quit();
|
|
}
|
|
if (appreloading) {
|
|
reloadall();
|
|
}
|
|
if (isopennewproject) {
|
|
dialog.showOpenDialog(win, {
|
|
title: 'Open Project',
|
|
defaultPath: app.getPath('documents'),
|
|
filters: [
|
|
{ name: 'ComputerCraft Project', extensions: ['ccp'] }
|
|
],
|
|
properties: ['openFile']
|
|
}).then(result => {
|
|
if (!result.canceled) {
|
|
const filePath = result.filePaths[0];
|
|
|
|
fs.readFile(filePath, 'utf8', (err, json) => {
|
|
if (err) {
|
|
console.error('Error loading workspace:', err);
|
|
return;
|
|
}
|
|
win.webContents.send('load-workspace', json);
|
|
|
|
currentprojectpath = result.filePaths[0]
|
|
currentprojectname = path.basename(result.filePaths[0]);
|
|
currentprojectopen = true;
|
|
|
|
win.setTitle(`${currentprojectname} | ccIDE v${version}`)
|
|
});
|
|
|
|
}
|
|
}).catch(err => {
|
|
console.error('Error showing open dialog:', err);
|
|
});
|
|
}
|
|
}
|
|
});
|
|
}
|
|
});
|
|
|
|
ipc.on('export-lua', (event, data) => {
|
|
dialog.showSaveDialog(win, {
|
|
title: 'Save Project',
|
|
defaultPath: path.join(app.getPath('documents'), 'main.lua'),
|
|
filters: [
|
|
{ extensions: ['lua'] }
|
|
]
|
|
}).then(result => {
|
|
if (!result.canceled) {
|
|
fs.writeFile(result.filePath, data, (err) => {
|
|
if (err) {
|
|
console.error('Error exporting lua from project:', err);
|
|
dialog.showErrorBox("Export Lua Error", err.message)
|
|
}
|
|
});
|
|
}
|
|
}).catch(err => {
|
|
console.error('Error exporting lua from project:', err);
|
|
dialog.showErrorBox("Export Lua Error", err.message)
|
|
});
|
|
});
|
|
|
|
ipc.on('workspace-notsave', (event) => {
|
|
win.setTitle(`${currentprojectname}* | ccIDE v${version}`)
|
|
currentworkspacechange = true;
|
|
})
|
|
ipc.on('workspace-unsave', (event) => {
|
|
currentworkspacechange = true;
|
|
})
|
|
|
|
// Listen for the close event of the main window
|
|
/*
|
|
win.on('close', (event) => {
|
|
event.preventDefault()
|
|
if (currentprojectopen && !currentworkspacechange) {
|
|
const result = dialog.showMessageBoxSync({
|
|
type: 'question',
|
|
buttons: ['Save', 'Don\'t Save', 'Cancel'],
|
|
defaultId: 2,
|
|
title: 'Save Changes',
|
|
message: "Your project is not saved",
|
|
});
|
|
if (result === 1) {
|
|
// Don't save, continue closing
|
|
win.close();
|
|
} else if (result === 0) {
|
|
// Save and then quit
|
|
appexiting = true;
|
|
win.webContents.send('save-workspace-request');
|
|
}
|
|
} else {
|
|
win.destroy();
|
|
}
|
|
});
|
|
*/
|
|
|
|
win.on("closed", () => {
|
|
logger.info("Exiting...")
|
|
if (!splash.isDestroyed()) {
|
|
splash.close()
|
|
}
|
|
})
|
|
|
|
})
|
|
|
|
app.on('window-all-closed', () => {
|
|
if (process.platform !== 'darwin') {
|
|
app.quit();
|
|
}
|
|
logger.info("Exited")
|
|
}); |