From 1fa735b54d580d37539c5eb6ecd45e728f6b33c5 Mon Sep 17 00:00:00 2001 From: itdominator <1itdominator@gmail.com> Date: Sun, 1 Jun 2025 13:49:18 -0500 Subject: [PATCH] Constructed menu; moved files to sub newton folder; WIP save system added --- newton/app.js | 77 +++++++++++++++++++++++++++ newton/fs.js | 59 ++++++++++++++++++++ main.js => newton/main.js | 39 +++----------- app.js => newton/menu.js | 77 +++------------------------ preload.js => newton/preload.js | 0 package.json | 2 +- src/app/editor/ace/ace-editor.base.ts | 11 +++- src/app/editor/editors.component.ts | 24 +++++---- 8 files changed, 171 insertions(+), 118 deletions(-) create mode 100644 newton/app.js create mode 100644 newton/fs.js rename main.js => newton/main.js (59%) rename app.js => newton/menu.js (63%) rename preload.js => newton/preload.js (100%) diff --git a/newton/app.js b/newton/app.js new file mode 100644 index 0000000..5fa5fea --- /dev/null +++ b/newton/app.js @@ -0,0 +1,77 @@ +const { BrowserWindow } = require('electron'); +const path = require('node:path'); + +const { menu } = require('./menu'); +const { newtonFs } = require('./fs'); + + +const BASE_PATH = '../dist/app'; +const ICON_PATH = `${BASE_PATH}/resources/newton.png`; + +let args = []; + + + +// Note: https://tinydew4.gitbooks.io/electron/content/api/browser-window.html +const createWindow = (startType = "build", debug = false, args = []) => { + this.args = args; + + const win = new BrowserWindow({ + title: "Newton", + width: 800, + height: 600, + minWidth: 800, + minHeight: 600, + show: false, + transparent: true, + icon: path.join(__dirname, ICON_PATH), + webPreferences: { + preload: path.join(__dirname, 'preload.js'), + contextIsolation: true, + enableRemoteModule: false, + plugins: true, + webSecurity: true, + sandbox: true, + } + }); + + win.once('ready-to-show', () => { + win.show() + }); + + menu.load(win); + + // win.setAutoHideMenuBar(true) + + if (debug == true) { + win.webContents.openDevTools(); + } + + if (startType === "build") { + win.loadFile( + path.join(__dirname, `${BASE_PATH}/index.html`) + ); + } + + if (startType === "ng-serve") { + win.loadURL('http://localhost:4200'); + } + +// const child = new BrowserWindow({parent: win, modal: true, show: false}) +// child.loadFile( +// path.join(__dirname, `${BASE_PATH}/index.html`) +// ); +// child.once('ready-to-show', () => { +// child.show() +// }); + +} + + + +module.exports = { + newton: { + createWindow: createWindow, + fs: newtonFs, + } +}; \ No newline at end of file diff --git a/newton/fs.js b/newton/fs.js new file mode 100644 index 0000000..13ed13c --- /dev/null +++ b/newton/fs.js @@ -0,0 +1,59 @@ +const { dialog } = require('electron'); +const path = require('node:path'); +const fs = require('node:fs'); +const os = require('os') + + + +const BASE_PATH = '../dist/app'; +const LSP_CONFIG_PATH = `${BASE_PATH}/resources/lsp-servers-config.json`; + + + +const getFileContents = (_path, useRelativePath = false) => { + console.log(`Getting Contents For: ${_path}`); + + try { + if (!useRelativePath) { + return fs.readFileSync(_path, 'utf8'); + } else { + return fs.readFileSync(path.join(__dirname, _path), 'utf8'); + } + } catch(err) { + return `{"message": {"type": "error", "text": "Error: Could not read ${_path}"}}`; + } +} + +const getLspConfigData = () => { + const config = getFileContents(LSP_CONFIG_PATH, true); + return config.replaceAll("{user.home}", os.homedir()); +} + +const saveFile = (fpath, content) => { + fs.writeFile(fpath, content, (err) => { + if (!err) return + console.error("An error ocurred writing to the file " + err.message) + }); +} + +const saveFileAs = (content) => { + dialog.showSaveDialog().then((response) => { + if (response.canceled) { + console.log("You didn't save the file"); + return; + } + + saveFile(response.filePath, content); + }); +} + + + +module.exports = { + newtonFs: { + saveFile: saveFile, + saveFileAs: saveFileAs, + getFileContents: getFileContents, + getLspConfigData: getLspConfigData + } +}; \ No newline at end of file diff --git a/main.js b/newton/main.js similarity index 59% rename from main.js rename to newton/main.js index 64084ac..3533986 100644 --- a/main.js +++ b/newton/main.js @@ -3,11 +3,9 @@ try { } catch {} +const { app, ipcMain } = require('electron'); -const { app, ipcMain, dialog } = require('electron'); const { newton } = require('./app'); -const path = require('node:path'); -const fs = require('node:fs'); @@ -39,41 +37,16 @@ const loadArgs = () => { console.log(index + ': ' + val); console.log(); }); - -} - -const saveFile = (path, content) => { - console.log("..."); -} - -const saveFileAs = (content) => { - console.log(content); - dialog.showSaveDialog((fileName) => { - console.log(fileName); - - if (fileName === undefined){ - console.log("You didn't save the file"); - return; - } - - // fileName is a string that contains the path and filename created in the save file dialog. - fs.writeFile(fileName, content, (err) => { - if(err){ - alert("An error ocurred creating the file "+ err.message) - } - - alert("The file has been succesfully saved"); - }); - }); } const loadHandlers = () => { - ipcMain.handle('getLspConfigData', (eve) => newton.getLspConfigData()); - ipcMain.handle('getFileContents', (eve, file) => newton.getFileContents(file)); - ipcMain.handle('saveFile', (eve, path, content) => saveFile(path, "Some text to save into the file")); - ipcMain.handle('saveFileAs', (eve, content) => saveFileAs("Some text to save into the file")); + ipcMain.handle('getLspConfigData', (eve) => newton.fs.getLspConfigData()); + ipcMain.handle('getFileContents', (eve, file) => newton.fs.getFileContents(file)); + ipcMain.handle('saveFile', (eve, path, content) => newton.fs.saveFile(path, content)); + ipcMain.handle('saveFileAs', (eve, content) => newton.fs.saveFileAs(content)); } + app.whenReady().then(() => { loadArgs(); loadHandlers(); diff --git a/app.js b/newton/menu.js similarity index 63% rename from app.js rename to newton/menu.js index bd8b1b1..0afbd4c 100644 --- a/app.js +++ b/newton/menu.js @@ -1,53 +1,9 @@ -const { BrowserWindow, Menu } = require('electron'); -const path = require('node:path'); -const fs = require('node:fs'); -const os = require('os') +const { Menu } = require('electron'); +const path = require('node:path'); -// const BASE_PATH = 'dist/app/browser'; -const BASE_PATH = 'dist/app'; -const ICON_PATH = `${BASE_PATH}/resources/newton.png`; -const LSP_CONFIG_PATH = `${BASE_PATH}/resources/lsp-servers-config.json`; -let args = []; - - - -const createWindow = (startType = "build", debug = false, args = []) => { - this.args = args; - - const win = new BrowserWindow({ - width: 800, - height: 600, - transparent: true, - icon: path.join(__dirname, ICON_PATH), - webPreferences: { - preload: path.join(__dirname, 'preload.js'), - contextIsolation: true, - enableRemoteModule: false, - } - }); - - setupMenu(win); - - // win.setAutoHideMenuBar(true) - - if (debug == true) { - win.webContents.openDevTools(); - } - - if (startType === "build") { - win.loadFile( - path.join(__dirname, `${BASE_PATH}/index.html`) - ); - } - - if (startType === "ng-serve") { - win.loadURL('http://localhost:4200'); - } -} - -const setupMenu = (win) => { +const load = (win) => { const menu = Menu.buildFromTemplate([ { label: "File", @@ -57,7 +13,7 @@ const setupMenu = (win) => { click: () => win.webContents.send('menu-actions', "new-file") }, { label: 'Open', - click: () => win.webContents.send('load-files', [path.join(__dirname, `${BASE_PATH}/index.html`)]) + click: () => win.webContents.send('load-files', [path.join(__dirname, `menu.js`)]) }, { label: 'Terminal', click: () => {} @@ -140,31 +96,10 @@ const setupMenu = (win) => { Menu.setApplicationMenu(menu) } -const getFileContents = (_path, useRelativePath = false) => { - console.log(`Getting Contents For: ${_path}`); - - try { - if (!useRelativePath) { - return fs.readFileSync(_path, 'utf8'); - } else { - return fs.readFileSync(path.join(__dirname, _path), 'utf8'); - } - } catch(err) { - return `{"message": {"type": "error", "text": "Error: Could not read ${_path}"}}`; - } -} - -const getLspConfigData = () => { - const config = getFileContents(LSP_CONFIG_PATH, true); - return config.replaceAll("{user.home}", os.homedir()); -} - module.exports = { - newton: { - createWindow: createWindow, - getFileContents: getFileContents, - getLspConfigData: getLspConfigData + menu: { + load: load } }; \ No newline at end of file diff --git a/preload.js b/newton/preload.js similarity index 100% rename from preload.js rename to newton/preload.js diff --git a/package.json b/package.json index b59b86f..0577adc 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "Newton Editor", "version": "0.0.1", "description": "A uniquly simple quasi-IDE for hardcore developers.", - "main": "main.js", + "main": "newton/main.js", "scripts": { "app": "ng build --base-href ./ && electron . --trace-warnings --start-as=build", "electron-build": "electron . --trace-warnings --start-as=build", diff --git a/src/app/editor/ace/ace-editor.base.ts b/src/app/editor/ace/ace-editor.base.ts index 2e797a0..f6a00c2 100644 --- a/src/app/editor/ace/ace-editor.base.ts +++ b/src/app/editor/ace/ace-editor.base.ts @@ -1,6 +1,7 @@ import { Directive, ElementRef, Input, ViewChild } from '@angular/core'; import { EditorSettings } from "../../common/configs/editor.config"; +import { NewtonFile } from '../../common/types/file.type'; @@ -12,6 +13,7 @@ export class AceEditorBase { uuid!: string; cutBuffer: string = ""; timerId: number = -1; + activeFile!: NewtonFile; constructor( @@ -23,8 +25,13 @@ export class AceEditorBase { } protected saveFile() { - const text = this.editor.session.getValue(); -// window.fs.saveFile(text); + if (!this.activeFile) { + this.saveFileAs(); + return; + } + + const text = this.activeFile.session.getValue(); + window.fs.saveFile(this.activeFile.path, text); } protected saveFileAs() { diff --git a/src/app/editor/editors.component.ts b/src/app/editor/editors.component.ts index ae15db7..9a3e875 100644 --- a/src/app/editor/editors.component.ts +++ b/src/app/editor/editors.component.ts @@ -75,8 +75,8 @@ export class EditorsComponent { this.addTab(file); } - let session = this.files.get(paths[ paths.length - 1 ]).session; - this.setSession(session); + let file = this.files.get(paths[ paths.length - 1 ]); + this.setSession(file); }); window.main.onMenuActions(async (action: string) => { @@ -130,23 +130,25 @@ export class EditorsComponent { } protected onFileDropped(files: any) { - this.loadFilesList(files).then((session: EditSession | undefined | null) => { - this.setSession(session); + this.loadFilesList(files).then((file: NewtonFile | undefined | null) => { + this.setSession(file); }); } - private async setSession(session: EditSession | undefined | null) { - if ( !session ) return; + private async setSession(file: NewtonFile | undefined | null) { + if ( !file ) return; + let editorComponent = this.getActiveEditorComponent(); + let editor = editorComponent.editor; - let editor = this.getActiveEditor(); - editor?.setSession(session); + editorComponent.activeFile = file; + editor.setSession(file.session); } private getSession() { let editorComponent = this.editors.get(this.activeEditor)?.instance; let editor = editorComponent.editor; - return editor?.getSession(); + return editor.getSession(); } private getActiveEditorComponent(): any { @@ -159,7 +161,7 @@ export class EditorsComponent { return editor; } - private async loadFilesList(files: Array): Promise { + private async loadFilesList(files: Array): Promise { for (let i = 0; i < files.length; i++) { const file = files[i]; const path = window.fs.getPathForFile(file); @@ -171,7 +173,7 @@ export class EditorsComponent { this.addTab(file); } - return files[ files.length - 1 ].session; + return files[ files.length - 1 ]; } private async addFile(path: string, file: NewtonFile): Promise {