Skip to content

Commit

Permalink
feat: electron app
Browse files Browse the repository at this point in the history
  • Loading branch information
hrenaud committed May 26, 2024
1 parent 1679660 commit 7926172
Show file tree
Hide file tree
Showing 8 changed files with 94 additions and 52 deletions.
2 changes: 2 additions & 0 deletions electron-react/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -90,3 +90,5 @@ typings/

# Electron-Forge
out/

reports/
25 changes: 6 additions & 19 deletions electron-react/README.md
Original file line number Diff line number Diff line change
@@ -1,22 +1,9 @@
### electron-react-starter
# ELECTON-REACT-APP (ecoindex)

This is a starter template that I made for myself while learning electron. It is a modified version of the [Vite + Typescript](https://www.electronforge.io/templates/vite-+-typescript) template from electron-forge.
> https://github.com/mongj/electron-react-starter
In addition to the template, React has been added to the renderer. TailwindCSS and shadcn-ui have also been set up.
## TODO

To install the depencies and run the app in dev mode:

```
yarn
yarn start
```

To package and distribute the app:

```
yarn package
yarn make
yarn publish
```

This corresponds to the 3 build commands available via electron-forge CLI. For more information, see electron-forge's [documentation](https://www.electronforge.io/core-concepts/build-lifecycle).
- [ ] enregistrer le chemin de base, mettre un chemin par défaut ~/ecoindex-exports
- [ ] Faire une version simple, multiple urls
- [ ] Faire une version complexe, avec des options
12 changes: 6 additions & 6 deletions electron-react/forge.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,12 +58,12 @@ const config: ForgeConfig = {
// at package time, before code signing the application
new FusesPlugin({
version: FuseVersion.V1,
[FuseV1Options.RunAsNode]: false,
[FuseV1Options.EnableCookieEncryption]: true,
[FuseV1Options.EnableNodeOptionsEnvironmentVariable]: false,
[FuseV1Options.EnableNodeCliInspectArguments]: false,
[FuseV1Options.EnableEmbeddedAsarIntegrityValidation]: true,
[FuseV1Options.OnlyLoadAppFromAsar]: true,
// [FuseV1Options.RunAsNode]: true,
// [FuseV1Options.EnableCookieEncryption]: true,
// [FuseV1Options.EnableNodeOptionsEnvironmentVariable]: true,
// [FuseV1Options.EnableNodeCliInspectArguments]: true,
// [FuseV1Options.EnableEmbeddedAsarIntegrityValidation]: true,
// [FuseV1Options.OnlyLoadAppFromAsar]: true,
}),
],
}
Expand Down
27 changes: 27 additions & 0 deletions electron-react/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,19 @@ import { useState } from 'react'
function App() {
const [counter, setCounter] = useState(0)

function showNotification(
title = 'Hello',
body = 'Hello, world!',
silent = false,
) {
// new window.Notification(title, {
// body: body,
// silent,
// })
// new Notification({ title, body, silent }).show()
new window.Notification(title, { body: body, silent })
}

window.electronAPI.onUpdateCounter((value: number) => {
setCounter(counter + value)
})
Expand All @@ -13,6 +26,12 @@ function App() {
window.electronAPI.onMenuSetFolderOuput((value: string) => {
window.electronAPI.handleSetFolderOuput()
})
window.electronAPI.doNotification(
(title: string, body: string, silent: boolean) => {
showNotification(title, body, silent)
console.log(title, body, silent)
},
)

return (
<div className="flex h-full w-full flex-col place-content-center place-items-center gap-8 p-8 text-center">
Expand All @@ -24,6 +43,13 @@ function App() {
</div>
<div className="flex w-full max-w-2xl flex-col gap-4 rounded-lg border border-zinc-200 p-4">
<span className="text-xl font-bold">IPC</span>
<Button
onClick={() => {
window.electronAPI.notificationApi.sendNotification('mon message')
}}
>
Notify
</Button>
<Button
onClick={() => {
window.electronAPI.setTitle(
Expand Down Expand Up @@ -69,6 +95,7 @@ function App() {
>
Install Puppeteer Chrome Browser
</Button>
<p id="output">Click it to see the effect in this interface.</p>
<div>
Go to the top left menu bar to update counter! (main to renderer)
</div>
Expand Down
4 changes: 4 additions & 0 deletions electron-react/src/interface.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ export interface IElectronAPI {
onMenuInstallPuppeteerBrowser: (callback: (value: string) => void) => void
onMenuSetFolderOuput: (callback: (value: string) => void) => void
onUpdateCounter: (callback: (value: number) => void) => void
doNotification: (
callback: (title: string, body: string, silent: boolean) => void,
) => void
notificationApi: { sendNotification: (message: string) => void }
}

declare global {
Expand Down
52 changes: 31 additions & 21 deletions electron-react/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,27 +12,27 @@ import { executablePath, default as puppeteer } from 'puppeteer'
import { spawn } from 'child_process'
import settings from 'electron-settings'
import { IpcMainEvent } from 'electron/main'
import os from 'os'
import path from 'path'
import { updateElectronApp } from 'update-electron-app'

console.log('File used for Persisting Data - ' + settings.file())

function welcomeNotification() {
if (Notification.isSupported()) {
const initNotif = new Notification()
initNotif.title = 'Ecoindex App is started!'
initNotif.body = 'Hello 👋'
initNotif.silent = true
initNotif.show()
showNotification('Ecoindex App is started!', 'Hello 👋', true)
}
}

function showNotification(title = 'Hello', body = 'Hello, world!') {
const startNotif = new Notification()
startNotif.title = title
startNotif.body = body
startNotif.show()
function showNotification(
title = 'Hello',
body = 'Hello, world!',
silent = false,
) {
// new window.Notification(title, {
// body: body,
// silent,
// })
new Notification({ title, body, silent }).show()
}

// Handle creating/removing shortcuts on Windows when installing/uninstalling.
Expand All @@ -46,23 +46,23 @@ function handleSetTitle(event: IpcMainEvent, title: string) {
win.setTitle(title)
}

async function handleFolderOuputSelector() {
async function handleFolderOuputSelector(event: IpcMainEvent) {
const { canceled, filePaths } = await dialog.showOpenDialog({
properties: ['openDirectory'],
})
if (!canceled) {
return filePaths[0]
}
}
async function handleInstallPuppeteerBrowser() {
async function checkPuppeteerBrowserVersion(version: string) {
console.log('targetVersion', version)
async function handleInstallPuppeteerBrowser(event: IpcMainEvent) {
console.log('handleInstallPuppeteerBrowser')

console.log('defaultPath', executablePath())
async function checkPuppeteerBrowserVersion(version: string) {
const path = executablePath().replace(
/(\d+\.)(\d+\.)(\d+\.)(\d+)/gm,
versionToCheck,
)
console.log('defaultPath', executablePath())
console.log('newPath', path)

const browser = await puppeteer.launch({
Expand All @@ -72,7 +72,6 @@ async function handleInstallPuppeteerBrowser() {
})

const installedVersion = await browser.version()
console.log('installedVersion', installedVersion)

await browser.close()

Expand All @@ -92,13 +91,13 @@ async function handleInstallPuppeteerBrowser() {
return
}

console.log('installPuppeteerBrowser')
showNotification(
'Puppeteer browser installation started...',
'This process may take a few minutes',
)

const ls = spawn('npx', [
' --yes',
'puppeteer',
'browsers',
'install',
Expand All @@ -117,13 +116,19 @@ async function handleInstallPuppeteerBrowser() {
})
}

async function handleLaunchEcoindexSimpleCollect() {
async function handleLaunchEcoindexSimpleCollect(event: IpcMainEvent) {
console.log('handleLaunchEcoindexSimpleCollect')
showNotification(
'Collect Ecoindex is started...',
'This process may take a few minutes',
)
return
const ls = spawn('npx', ['lighthouse-plugin-ecoindex', 'collect', '-d'])
// return
const ls = spawn('npx', [
'--yes',
'lighthouse-plugin-ecoindex',
'collect',
'-d',
])
ls.stdout.on('data', function (data) {
console.log(data.toString())
})
Expand All @@ -144,6 +149,7 @@ const createWindow = () => {
height: 600,
webPreferences: {
nodeIntegration: true,
contextIsolation: true,
preload: path.join(__dirname, 'preload.js'),
},
})
Expand Down Expand Up @@ -203,6 +209,10 @@ const createWindow = () => {
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.whenReady().then(() => {
ipcMain.on('notify', (_event, message) => {
new Notification({ title: 'Notification', body: message }).show()
// showNotification('Notification', message)
})
ipcMain.on('set-title', handleSetTitle)
ipcMain.handle('handleInstallPuppeteerBrowser', handleInstallPuppeteerBrowser)
ipcMain.handle(
Expand Down
11 changes: 11 additions & 0 deletions electron-react/src/preload.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,13 @@ contextBridge.exposeInMainWorld('versions', {
})

contextBridge.exposeInMainWorld('electronAPI', {
// to test
notificationApi: {
sendNotification(message: string) {
console.log(message)
ipcRenderer.send('notify', message)
},
},
setTitle: (title: string) => ipcRenderer.send('set-title', title),
handleSetFolderOuput: () => ipcRenderer.invoke('dialog:handleSetFolderOuput'),
handleLaunchEcoindexSimpleCollect: () =>
Expand All @@ -17,6 +24,10 @@ contextBridge.exposeInMainWorld('electronAPI', {
ipcRenderer.on('menu-install-puppeteer-browser', (_event, value: string) =>
callback(value),
),
doNotification: (callback: (value: string) => void) =>
ipcRenderer.on('menu-install-puppeteer-browser', (_event, value: string) =>
callback(value),
),
onMenuSetFolderOuput: (callback: (value: string) => void) =>
ipcRenderer.on('menu-set-folder-output', (_event, value: string) =>
callback(value),
Expand Down
13 changes: 7 additions & 6 deletions electron-react/src/renderer.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import "./index.css";
import App from "./App";
import React from "react";
import ReactDOM from "react-dom/client";
import './index.css'

ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render(
import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App'

ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render(
<React.StrictMode>
<App />
</React.StrictMode>,
);
)

0 comments on commit 7926172

Please sign in to comment.