adds the launcher

This commit is contained in:
2026-06-16 09:59:50 +02:00
parent 87fcf9bf93
commit d5dbf7187d
10 changed files with 419 additions and 65 deletions

View File

@@ -1,7 +1,7 @@
import { join, sep } from 'node:path'
import { app, dialog, shell, BrowserWindow, ipcMain, Menu } from 'electron'
import { watch, type FSWatcher } from 'chokidar'
import { getName, getRoot, openDialog } from './project'
import { addRecentProject, getName, getRecentProjects, getRoot, openDialog, setRoot } from './project'
import { readAll, readProjectFile, readTree, writeProjectFile } from './fs-service'
import { commit, discard, load, stage, unstage } from './git-service'
import { createPty, killAllPtys, killPty, ptyAvailable, resizePty, writePty } from './pty-service'
@@ -39,7 +39,7 @@ function startConfigWatcher(): void {
async function openFolderFlow(win: BrowserWindow | null): Promise<boolean> {
const next = await openDialog(win)
if (!next) return false
await resolveConfig(getRoot())
await resolveConfig(next)
startWatcher()
startConfigWatcher()
return true
@@ -91,17 +91,25 @@ function registerIpc(): void {
await openFolderFlow(BrowserWindow.fromWebContents(e.sender))
return { root: getRoot(), name: getName() }
})
ipcMain.handle('projects:recent', () => getRecentProjects())
ipcMain.handle('project:openPath', async (_e, path: string) => {
setRoot(path)
const r = getRoot()
if (r) { await resolveConfig(r); startWatcher(); startConfigWatcher() }
broadcast('project:changed')
return { root: getRoot(), name: getName() }
})
ipcMain.handle('fs:tree', () => readTree(getRoot()))
ipcMain.handle('fs:files', () => readAll(getRoot()))
ipcMain.handle('fs:read', (_e, rel: string) => readProjectFile(getRoot(), rel))
ipcMain.handle('fs:write', (_e, rel: string, content: string) => writeProjectFile(getRoot(), rel, content))
ipcMain.handle('fs:tree', () => { const r = getRoot(); return r ? readTree(r) : null })
ipcMain.handle('fs:files', () => { const r = getRoot(); return r ? readAll(r) : {} })
ipcMain.handle('fs:read', (_e, rel: string) => { const r = getRoot(); return r ? readProjectFile(r, rel) : '' })
ipcMain.handle('fs:write', (_e, rel: string, content: string) => { const r = getRoot(); if (r) return writeProjectFile(r, rel, content) })
ipcMain.handle('git:load', () => load(getRoot()))
ipcMain.handle('git:stage', (_e, paths: string[]) => stage(getRoot(), paths))
ipcMain.handle('git:unstage', (_e, paths: string[]) => unstage(getRoot(), paths))
ipcMain.handle('git:commit', (_e, message: string) => commit(getRoot(), message))
ipcMain.handle('git:discard', (_e, paths: string[]) => discard(getRoot(), paths))
ipcMain.handle('git:load', () => { const r = getRoot(); return r ? load(r) : null })
ipcMain.handle('git:stage', (_e, paths: string[]) => { const r = getRoot(); if (r) return stage(r, paths) })
ipcMain.handle('git:unstage', (_e, paths: string[]) => { const r = getRoot(); if (r) return unstage(r, paths) })
ipcMain.handle('git:commit', (_e, message: string) => { const r = getRoot(); if (r) return commit(r, message) })
ipcMain.handle('git:discard', (_e, paths: string[]) => { const r = getRoot(); if (r) return discard(r, paths) })
ipcMain.handle('pty:available', () => ptyAvailable())
ipcMain.handle('pty:create', (e, kind: 'agent' | 'shell', cols: number, rows: number) => createPty(e.sender, kind, cols, rows))
@@ -112,11 +120,11 @@ function registerIpc(): void {
ipcMain.handle('config:get', () => getConfig())
ipcMain.handle('config:theme', () => getThemeCss())
ipcMain.handle('recent:get', () => getRecent(getRoot()))
ipcMain.handle('recent:set', (_e, list: string[]) => setRecent(getRoot(), list))
ipcMain.handle('recent:get', () => { const r = getRoot(); return r ? getRecent(r) : [] })
ipcMain.handle('recent:set', (_e, list: string[]) => { const r = getRoot(); if (r) return setRecent(r, list) })
ipcMain.handle('search:content', (_e, query: string) => searchContent(getRoot(), query))
ipcMain.handle('search:files', () => listFiles(getRoot()))
ipcMain.handle('search:content', (_e, query: string) => { const r = getRoot(); return r ? searchContent(r, query) : [] })
ipcMain.handle('search:files', () => { const r = getRoot(); return r ? listFiles(r) : [] })
ipcMain.handle('dialog:unsavedClose', async (e, path: string) => {
const win = BrowserWindow.fromWebContents(e.sender)
@@ -169,9 +177,13 @@ app.whenReady().then(async () => {
app.setName('Helder')
Menu.setApplicationMenu(buildAppMenu())
registerIpc()
await resolveConfig(getRoot())
startWatcher()
startConfigWatcher()
const initialRoot = getRoot()
if (initialRoot) {
await resolveConfig(initialRoot)
await addRecentProject(initialRoot)
startWatcher()
startConfigWatcher()
}
createWindow()
app.on('activate', () => {