diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..400e2a8 --- /dev/null +++ b/.prettierignore @@ -0,0 +1,5 @@ +node_modules/ +dist/ +build/ +.env +*.log diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..5fcd8a7 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,3 @@ +{ + "tabWidth": 4 +} diff --git a/forge.config.ts b/forge.config.ts index eb80f6a..c877423 100644 --- a/forge.config.ts +++ b/forge.config.ts @@ -25,7 +25,7 @@ const config: ForgeConfig = { build: [ { // `entry` is just an alias for `build.lib.entry` in the corresponding file of `config`. - entry: 'src/main.ts', + entry: 'src/main/main.ts', config: 'vite.config.ts', target: 'main', }, diff --git a/index.html b/index.html index 57ec202..eea3bd7 100644 --- a/index.html +++ b/index.html @@ -5,7 +5,11 @@ Miller code editor -
Miller code editor - welcome!
+
Miller code editor - welcome! + + + N/A +
- + diff --git a/package-lock.json b/package-lock.json index 277766f..c59dcb8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -29,6 +29,7 @@ "electron": "37.2.6", "eslint": "^8.57.1", "eslint-plugin-import": "^2.32.0", + "prettier": "^3.6.2", "typescript": "~4.5.4", "vanjs-core": "^1.5.5", "vanjs-ext": "^0.6.3", diff --git a/package.json b/package.json index e5864c9..ada01b5 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,8 @@ "package": "electron-forge package", "make": "electron-forge make", "publish": "electron-forge publish", - "lint": "eslint --ext .ts,.tsx ." + "lint": "eslint --ext .ts,.tsx .", + "format": "prettier --write \"src/**/*.{js,ts,tsx,css,html}\"" }, "keywords": [], "author": { @@ -35,6 +36,7 @@ "electron": "37.2.6", "eslint": "^8.57.1", "eslint-plugin-import": "^2.32.0", + "prettier": "^3.6.2", "typescript": "~4.5.4", "vanjs-core": "^1.5.5", "vanjs-ext": "^0.6.3", diff --git a/src/app/foldernav.ts b/src/app/foldernav.ts new file mode 100644 index 0000000..8342309 --- /dev/null +++ b/src/app/foldernav.ts @@ -0,0 +1,8 @@ +import van from "vanjs-core" +const v = van.tags + +document.getElementById("openFolder").addEventListener("click", async () => { + const folderPath = await window.electronAPI.openFolder(); + document.getElementById("currentFolder").innerText = folderPath; +}) + diff --git a/src/index.css b/src/app/index.css similarity index 78% rename from src/index.css rename to src/app/index.css index 499afe8..40efc3b 100644 --- a/src/index.css +++ b/src/app/index.css @@ -1,16 +1,7 @@ -/* body { - font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, - Arial, sans-serif; - margin: auto; - max-width: 38rem; - padding: 2rem; -} */ - +/* Grid layout stuff (main) */ body { width: 100vw; height: 100vh; - /* margin: 0; */ - /* padding: 0; */ display: grid; grid-template-rows: auto minmax(0, 1fr); grid-template-columns: auto minmax(0, 4fr); @@ -41,6 +32,8 @@ aside { width: 200px; } +/* Editor grid stuff */ + #editorGrid { display: grid; height: minmax(0, 100%); @@ -57,3 +50,5 @@ aside { .editorWrapper { min-width: fit-content; } + +/* Navbar styling */ diff --git a/src/pico.jade.css b/src/app/pico.jade.css similarity index 100% rename from src/pico.jade.css rename to src/app/pico.jade.css diff --git a/src/renderer.ts b/src/app/renderer.ts similarity index 98% rename from src/renderer.ts rename to src/app/renderer.ts index 6d9e334..c6cef21 100644 --- a/src/renderer.ts +++ b/src/app/renderer.ts @@ -37,6 +37,8 @@ import { basicSetup } from "codemirror" import { EditorView } from "@codemirror/view" import { oneDark } from "@codemirror/theme-one-dark" +import './foldernav.ts' + const fixedHeightEditor = EditorView.theme({ "&": { height: "100%", diff --git a/src/main/fileOperations.ts b/src/main/fileOperations.ts new file mode 100644 index 0000000..9e31f02 --- /dev/null +++ b/src/main/fileOperations.ts @@ -0,0 +1,26 @@ +// src/main/fileOperations.ts +// Handles file operations for the main process + +import { dialog, BrowserWindow } from 'electron'; +import fs from 'fs'; +import path from 'path'; + +export async function handleOpenFolder(mainWindow: BrowserWindow) { + const result = await dialog.showOpenDialog(mainWindow, { + properties: ['openDirectory'] + }); + if (!result.canceled && result.filePaths.length > 0) { + const folderPath = result.filePaths[0]; + return folderPath; + } + return null; +} + +export function readFolderContents(folderPath: string): string[] { + try { + return fs.readdirSync(folderPath).map(file => path.join(folderPath, file)); + } catch (err) { + console.error('Error reading folder:', err); + return []; + } +} diff --git a/src/main.ts b/src/main/main.ts similarity index 69% rename from src/main.ts rename to src/main/main.ts index 352f594..9aadba2 100644 --- a/src/main.ts +++ b/src/main/main.ts @@ -1,4 +1,5 @@ -import { app, BrowserWindow } from 'electron'; +import { app, BrowserWindow, ipcMain } from 'electron'; +import { handleOpenFolder, readFolderContents } from './fileOperations'; import path from 'node:path'; import started from 'electron-squirrel-startup'; @@ -31,8 +32,26 @@ const createWindow = () => { // This method will be called when Electron has finished // initialization and is ready to create browser windows. // Some APIs can only be used after this event occurs. + + +app.whenReady().then(() => { + ipcMain.handle("dialog:openFolder", async (event) => { + // Use the sender's window for correct dialog association + const senderWindow = BrowserWindow.fromWebContents(event.sender); + return await handleOpenFolder(senderWindow); + }); + createWindow(); + app.on('activate', function () { + if (BrowserWindow.getAllWindows().length === 0) createWindow(); + }); +}); + + app.on('ready', createWindow); + + + // Quit when all windows are closed, except on macOS. There, it's common // for applications and their menu bar to stay active until the user quits // explicitly with Cmd + Q. @@ -41,14 +60,3 @@ app.on('window-all-closed', () => { app.quit(); } }); - -app.on('activate', () => { - // On OS X it's common to re-create a window in the app when the - // dock icon is clicked and there are no other windows open. - if (BrowserWindow.getAllWindows().length === 0) { - createWindow(); - } -}); - -// In this file you can include the rest of your app's specific main process -// code. You can also put them in separate files and import them here. diff --git a/src/preload.ts b/src/preload.ts index 5e9d369..412c25b 100644 --- a/src/preload.ts +++ b/src/preload.ts @@ -1,2 +1,8 @@ // See the Electron documentation for details on how to use preload scripts: // https://www.electronjs.org/docs/latest/tutorial/process-model#preload-scripts + +import { contextBridge, ipcRenderer } from 'electron' + +contextBridge.exposeInMainWorld('electronAPI', { + openFolder: () => ipcRenderer.invoke('dialog:openFolder') +}) diff --git a/src/types/global.d.ts b/src/types/global.d.ts new file mode 100644 index 0000000..76fe0c9 --- /dev/null +++ b/src/types/global.d.ts @@ -0,0 +1,9 @@ +// src/types/global.d.ts + +// Extend the Window interface to include electronAPI +interface Window { + electronAPI: { + openFolder: () => Promise; + // Add other methods as needed + }; +}