From 5ac7679b1e1d90a8e5ef487b015a21369dfa15c8 Mon Sep 17 00:00:00 2001 From: Bayangmbe Mounmo Date: Thu, 7 Dec 2023 01:18:49 +0100 Subject: [PATCH 01/12] added first template of basic-js-python --- examples/basic-js-python/README.md | 38 ++++++++ examples/basic-js-python/electron-builder.yml | 12 +++ examples/basic-js-python/main/background.js | 90 +++++++++++++++++++ .../main/helpers/create-window.js | 78 ++++++++++++++++ .../basic-js-python/main/helpers/index.js | 1 + examples/basic-js-python/main/preload.js | 17 ++++ examples/basic-js-python/package.json | 25 ++++++ .../basic-js-python/renderer/next.config.js | 10 +++ .../basic-js-python/renderer/pages/home.jsx | 63 +++++++++++++ .../basic-js-python/renderer/pages/next.jsx | 21 +++++ examples/basic-js-python/scripts/main.py | 9 ++ examples/basic-js-python/scripts/runner.sh | 8 ++ 12 files changed, 372 insertions(+) create mode 100644 examples/basic-js-python/README.md create mode 100644 examples/basic-js-python/electron-builder.yml create mode 100644 examples/basic-js-python/main/background.js create mode 100644 examples/basic-js-python/main/helpers/create-window.js create mode 100644 examples/basic-js-python/main/helpers/index.js create mode 100644 examples/basic-js-python/main/preload.js create mode 100644 examples/basic-js-python/package.json create mode 100644 examples/basic-js-python/renderer/next.config.js create mode 100644 examples/basic-js-python/renderer/pages/home.jsx create mode 100644 examples/basic-js-python/renderer/pages/next.jsx create mode 100644 examples/basic-js-python/scripts/main.py create mode 100644 examples/basic-js-python/scripts/runner.sh diff --git a/examples/basic-js-python/README.md b/examples/basic-js-python/README.md new file mode 100644 index 00000000..cf2b23a8 --- /dev/null +++ b/examples/basic-js-python/README.md @@ -0,0 +1,38 @@ +

+ +## Usage + +### Create an App + +``` +# with npx +$ npx create-nextron-app my-app --example basic-lang-javascript + +# with yarn +$ yarn create nextron-app my-app --example basic-lang-javascript + +# with pnpm +$ pnpm dlx create-nextron-app my-app --example basic-lang-javascript +``` + +### Install Dependencies + +``` +$ cd my-app + +# using yarn or npm +$ yarn (or `npm install`) + +# using pnpm +$ pnpm install --shamefully-hoist +``` + +### Use it + +``` +# development mode +$ yarn dev (or `npm run dev` or `pnpm run dev`) + +# production build +$ yarn build (or `npm run build` or `pnpm run build`) +``` diff --git a/examples/basic-js-python/electron-builder.yml b/examples/basic-js-python/electron-builder.yml new file mode 100644 index 00000000..1b5a3bbe --- /dev/null +++ b/examples/basic-js-python/electron-builder.yml @@ -0,0 +1,12 @@ +appId: com.example.nextron +productName: My Nextron App +copyright: Copyright © 2018 Yoshihide Shiono +directories: + output: dist + buildResources: resources +files: + - from: . + filter: + - package.json + - app +publish: null diff --git a/examples/basic-js-python/main/background.js b/examples/basic-js-python/main/background.js new file mode 100644 index 00000000..399856bd --- /dev/null +++ b/examples/basic-js-python/main/background.js @@ -0,0 +1,90 @@ +import { app, ipcMain } from 'electron'; +import serve from 'electron-serve' +import { createWindow } from './helpers' +const { exec } = require('child_process'); +const os = require('os'); +const path = require('path'); + +const isProd = process.env.NODE_ENV === 'production' + +function resolveHome(filepath) { + if (filepath.startsWith('~')) { + return path.join(os.homedir(), filepath.slice(1)); + } + return filepath; +} + +async function startProcess(event, value) { + if(event) { + /* + 'parentDir' is used to get this folder -> /Applications/.app/Contents/ + so that we can run our .sh file which will also launch the Python or Rust script. + So the script folder will be moved into parentDir/ in prod mode. + Note: this will only work if the target mahcine have Python or Rust installed. + */ + let scriptPath + if (isProd) { + const parentDir = path.dirname(path.dirname(path.dirname(__dirname))) + scriptPath = path.join(parentDir, 'scripts/runner.sh'); + } else { + scriptPath = path.join(__dirname, '../scripts/runner.sh'); + } + console.log(`DEBUG: scriptPath: ${scriptPath}`) + + exec(`sh ${scriptPath} ${value}`, (error, stdout, stderr) => { + if (error) { + console.error(`ERROR: Error executing post-install script: ${error}`); // will be seen only dev mode, not in prod mode + event.sender.send("log", error.message); // will be seen in both dev and prod mode (in the frontend) + return; + } + event.sender.send("log", "Python script executed successfully"); + event.sender.send("message", stdout); + }); + + // ~/.yourApp.log will be helpfull to log process in production mode + } +} + +ipcMain.on('run-sh', async (event, value) => { + console.log("DEBUG: starting process") // for dev mode + event.sender.send("log", "Running...") // for prod mode + await startProcess(event, value); + } +); + +if (isProd) { + serve({ directory: 'app' }) +} else { + app.setPath('userData', `${app.getPath('userData')} (development)`) +} + + +;(async () => { + await app.whenReady() + + const mainWindow = createWindow('main', { + width: 1000, + height: 600, + webPreferences: { + preload: path.join(__dirname, 'preload.js'), + }, + }) + + if (isProd) { + await mainWindow.loadURL('app://./home') + } else { + const port = process.argv[2] + await mainWindow.loadURL(`http://localhost:${port}/home`) + mainWindow.webContents.openDevTools() + } +})() + +app.on('window-all-closed', () => { + app.quit() +}) + +// ipcMain.on('message', async (event, arg) => { +// event.reply('message', `${arg} World!`) +// }) + + diff --git a/examples/basic-js-python/main/helpers/create-window.js b/examples/basic-js-python/main/helpers/create-window.js new file mode 100644 index 00000000..84efadf1 --- /dev/null +++ b/examples/basic-js-python/main/helpers/create-window.js @@ -0,0 +1,78 @@ +import { screen, BrowserWindow } from 'electron' +import Store from 'electron-store' + +export const createWindow = (windowName, options) => { + const key = 'window-state' + const name = `window-state-${windowName}` + const store = new Store({ name }) + const defaultSize = { + width: options.width, + height: options.height, + } + let state = {} + + const restore = () => store.get(key, defaultSize) + + const getCurrentPosition = () => { + const position = win.getPosition() + const size = win.getSize() + return { + x: position[0], + y: position[1], + width: size[0], + height: size[1], + } + } + + const windowWithinBounds = (windowState, bounds) => { + return ( + windowState.x >= bounds.x && + windowState.y >= bounds.y && + windowState.x + windowState.width <= bounds.x + bounds.width && + windowState.y + windowState.height <= bounds.y + bounds.height + ) + } + + const resetToDefaults = () => { + const bounds = screen.getPrimaryDisplay().bounds + return Object.assign({}, defaultSize, { + x: (bounds.width - defaultSize.width) / 2, + y: (bounds.height - defaultSize.height) / 2, + }) + } + + const ensureVisibleOnSomeDisplay = (windowState) => { + const visible = screen.getAllDisplays().some((display) => { + return windowWithinBounds(windowState, display.bounds) + }) + if (!visible) { + // Window is partially or fully not visible now. + // Reset it to safe defaults. + return resetToDefaults() + } + return windowState + } + + const saveState = () => { + if (!win.isMinimized() && !win.isMaximized()) { + Object.assign(state, getCurrentPosition()) + } + store.set(key, state) + } + + state = ensureVisibleOnSomeDisplay(restore()) + + const win = new BrowserWindow({ + ...state, + ...options, + webPreferences: { + nodeIntegration: false, + contextIsolation: true, + ...options.webPreferences, + }, + }) + + win.on('close', saveState) + + return win +} diff --git a/examples/basic-js-python/main/helpers/index.js b/examples/basic-js-python/main/helpers/index.js new file mode 100644 index 00000000..e1b9aad0 --- /dev/null +++ b/examples/basic-js-python/main/helpers/index.js @@ -0,0 +1 @@ +export * from './create-window' diff --git a/examples/basic-js-python/main/preload.js b/examples/basic-js-python/main/preload.js new file mode 100644 index 00000000..78349942 --- /dev/null +++ b/examples/basic-js-python/main/preload.js @@ -0,0 +1,17 @@ +import { contextBridge, ipcRenderer } from 'electron' + +const handler = { + send(channel, value) { + ipcRenderer.send(channel, value) + }, + on(channel, callback) { + const subscription = (_event, ...args) => callback(...args) + ipcRenderer.on(channel, subscription) + + return () => { + ipcRenderer.removeListener(channel, subscription) + } + }, +} + +contextBridge.exposeInMainWorld('ipc', handler) diff --git a/examples/basic-js-python/package.json b/examples/basic-js-python/package.json new file mode 100644 index 00000000..12b20c1e --- /dev/null +++ b/examples/basic-js-python/package.json @@ -0,0 +1,25 @@ +{ + "private": true, + "name": "my-nextron-app", + "description": "My application description", + "version": "1.0.0", + "author": "Yoshihide Shiono ", + "main": "app/background.js", + "scripts": { + "dev": "nextron", + "build": "nextron build", + "postinstall": "electron-builder install-app-deps" + }, + "dependencies": { + "electron-serve": "^1.1.0", + "electron-store": "^8.1.0" + }, + "devDependencies": { + "electron": "^26.2.2", + "electron-builder": "^24.6.4", + "next": "^12.3.4", + "nextron": "^8.12.0", + "react": "^18.2.0", + "react-dom": "^18.2.0" + } +} diff --git a/examples/basic-js-python/renderer/next.config.js b/examples/basic-js-python/renderer/next.config.js new file mode 100644 index 00000000..60e1d31c --- /dev/null +++ b/examples/basic-js-python/renderer/next.config.js @@ -0,0 +1,10 @@ +/** @type {import('next').NextConfig} */ +module.exports = { + trailingSlash: true, + images: { + unoptimized: true, + }, + webpack: (config) => { + return config + }, +} diff --git a/examples/basic-js-python/renderer/pages/home.jsx b/examples/basic-js-python/renderer/pages/home.jsx new file mode 100644 index 00000000..72f49da7 --- /dev/null +++ b/examples/basic-js-python/renderer/pages/home.jsx @@ -0,0 +1,63 @@ +import React from 'react' +import Head from 'next/head' +import Link from 'next/link' +import Image from 'next/image' + +export default function HomePage() { + const [log, setLog] = React.useState('') + const [value, setValue] = React.useState('5') + const [message, setMessage] = React.useState("") + + const handleChange = (event) => { + setValue(event.target.value) + setMessage("") + } + + React.useEffect(() => { + window.ipc.on('log', (log) => { + setLog(log) + }) + window.ipc.on('message', (msg) => { + setMessage(msg) + }) + }, []) + + return ( + + + Home - Nextron (basic-js-python) + +
+

+ ⚡ Electron + Next.js ⚡ - + + Go to next page + +

+ Logo image +
+
+ +

+ Calculate the sqaure of your number: + +

+ +

{log}

+

the square of {value} is {"-> "} {message}

+ +
+
+ ) +} diff --git a/examples/basic-js-python/renderer/pages/next.jsx b/examples/basic-js-python/renderer/pages/next.jsx new file mode 100644 index 00000000..19873ee8 --- /dev/null +++ b/examples/basic-js-python/renderer/pages/next.jsx @@ -0,0 +1,21 @@ +import React from 'react' +import Head from 'next/head' +import Link from 'next/link' + +export default function NextPage() { + return ( + + + Next - Nextron (basic-lang-javascript) + +
+

+ ⚡ Electron + Next.js ⚡ - + + Go to home page + +

+
+
+ ) +} diff --git a/examples/basic-js-python/scripts/main.py b/examples/basic-js-python/scripts/main.py new file mode 100644 index 00000000..31aee9a2 --- /dev/null +++ b/examples/basic-js-python/scripts/main.py @@ -0,0 +1,9 @@ +import sys, time + +def square_of_number(): + # time.sleep(3) # Simulate a long running process :), you can comment this line to have RT + print( int(sys.argv[1]) ** 2 ) + +if __name__ == "__main__": + square_of_number() + diff --git a/examples/basic-js-python/scripts/runner.sh b/examples/basic-js-python/scripts/runner.sh new file mode 100644 index 00000000..3bdc159e --- /dev/null +++ b/examples/basic-js-python/scripts/runner.sh @@ -0,0 +1,8 @@ +#!/bin/sh + +# get the directory of the script +script_dir="$(dirname "$0")" +cd $script_dir || exit 1 # cd to the script directory or exit if failed + +# run the app and pass the second argument to the app +echo $(python main.py $1) \ No newline at end of file From 949b50db9286a4cd70268347e56cf6faa63842c0 Mon Sep 17 00:00:00 2001 From: Bayangmbe Mounmo Date: Thu, 7 Dec 2023 01:23:07 +0100 Subject: [PATCH 02/12] added scripts --- examples/basic-js-python/renderer/pages/next.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/basic-js-python/renderer/pages/next.jsx b/examples/basic-js-python/renderer/pages/next.jsx index 19873ee8..0d2d67c2 100644 --- a/examples/basic-js-python/renderer/pages/next.jsx +++ b/examples/basic-js-python/renderer/pages/next.jsx @@ -6,7 +6,7 @@ export default function NextPage() { return ( - Next - Nextron (basic-lang-javascript) + Next - Nextron (basic-js-python)

From c58851b4c2bf03f622bc92efc57cb16aacb448a8 Mon Sep 17 00:00:00 2001 From: Bayangmbe Mounmo Date: Thu, 7 Dec 2023 01:49:42 +0100 Subject: [PATCH 03/12] included extraFiles --- examples/basic-js-python/package.json | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/examples/basic-js-python/package.json b/examples/basic-js-python/package.json index 12b20c1e..74936a2a 100644 --- a/examples/basic-js-python/package.json +++ b/examples/basic-js-python/package.json @@ -10,6 +10,15 @@ "build": "nextron build", "postinstall": "electron-builder install-app-deps" }, + "build": { + "extraFiles": [ + { + "from": "scripts/", + "to": "scripts/", + "filter": "**/*" + } + ] + }, "dependencies": { "electron-serve": "^1.1.0", "electron-store": "^8.1.0" From a2a953434c501c17b6df13e90df2c92f1c8d24d3 Mon Sep 17 00:00:00 2001 From: Bayangmbe Mounmo Date: Thu, 7 Dec 2023 01:51:53 +0100 Subject: [PATCH 04/12] security issue: removed console of --- examples/basic-js-python/main/background.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/basic-js-python/main/background.js b/examples/basic-js-python/main/background.js index 399856bd..bf97a6cd 100644 --- a/examples/basic-js-python/main/background.js +++ b/examples/basic-js-python/main/background.js @@ -29,7 +29,7 @@ async function startProcess(event, value) { } else { scriptPath = path.join(__dirname, '../scripts/runner.sh'); } - console.log(`DEBUG: scriptPath: ${scriptPath}`) + // console.log(`DEBUG: scriptPath: ${scriptPath}`) exec(`sh ${scriptPath} ${value}`, (error, stdout, stderr) => { if (error) { From a4211e0b10130bba9b013a548489fd8437efb82e Mon Sep 17 00:00:00 2001 From: Bayangmbe Mounmo Date: Thu, 7 Dec 2023 01:54:58 +0100 Subject: [PATCH 05/12] security issue: dynamic construction of the shell command --- examples/basic-js-python/main/background.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/examples/basic-js-python/main/background.js b/examples/basic-js-python/main/background.js index bf97a6cd..f98cb893 100644 --- a/examples/basic-js-python/main/background.js +++ b/examples/basic-js-python/main/background.js @@ -30,8 +30,9 @@ async function startProcess(event, value) { scriptPath = path.join(__dirname, '../scripts/runner.sh'); } // console.log(`DEBUG: scriptPath: ${scriptPath}`) + const cmd = `sh ${scriptPath} ${value}` - exec(`sh ${scriptPath} ${value}`, (error, stdout, stderr) => { + exec(cmd, (error, stdout, stderr) => { if (error) { console.error(`ERROR: Error executing post-install script: ${error}`); // will be seen only dev mode, not in prod mode event.sender.send("log", error.message); // will be seen in both dev and prod mode (in the frontend) From 1ca6c47b2b457f3d4e0fb2f47fc4b8cc788d3cf7 Mon Sep 17 00:00:00 2001 From: Shiono Yoshihide Date: Sat, 3 Feb 2024 16:55:57 +0900 Subject: [PATCH 06/12] chore: Remove unnecessary files --- .../main/helpers/create-window.js | 78 ------------------- .../basic-js-python/main/helpers/index.js | 1 - examples/basic-js-python/main/preload.js | 17 ---- 3 files changed, 96 deletions(-) delete mode 100644 examples/basic-js-python/main/helpers/create-window.js delete mode 100644 examples/basic-js-python/main/helpers/index.js delete mode 100644 examples/basic-js-python/main/preload.js diff --git a/examples/basic-js-python/main/helpers/create-window.js b/examples/basic-js-python/main/helpers/create-window.js deleted file mode 100644 index 84efadf1..00000000 --- a/examples/basic-js-python/main/helpers/create-window.js +++ /dev/null @@ -1,78 +0,0 @@ -import { screen, BrowserWindow } from 'electron' -import Store from 'electron-store' - -export const createWindow = (windowName, options) => { - const key = 'window-state' - const name = `window-state-${windowName}` - const store = new Store({ name }) - const defaultSize = { - width: options.width, - height: options.height, - } - let state = {} - - const restore = () => store.get(key, defaultSize) - - const getCurrentPosition = () => { - const position = win.getPosition() - const size = win.getSize() - return { - x: position[0], - y: position[1], - width: size[0], - height: size[1], - } - } - - const windowWithinBounds = (windowState, bounds) => { - return ( - windowState.x >= bounds.x && - windowState.y >= bounds.y && - windowState.x + windowState.width <= bounds.x + bounds.width && - windowState.y + windowState.height <= bounds.y + bounds.height - ) - } - - const resetToDefaults = () => { - const bounds = screen.getPrimaryDisplay().bounds - return Object.assign({}, defaultSize, { - x: (bounds.width - defaultSize.width) / 2, - y: (bounds.height - defaultSize.height) / 2, - }) - } - - const ensureVisibleOnSomeDisplay = (windowState) => { - const visible = screen.getAllDisplays().some((display) => { - return windowWithinBounds(windowState, display.bounds) - }) - if (!visible) { - // Window is partially or fully not visible now. - // Reset it to safe defaults. - return resetToDefaults() - } - return windowState - } - - const saveState = () => { - if (!win.isMinimized() && !win.isMaximized()) { - Object.assign(state, getCurrentPosition()) - } - store.set(key, state) - } - - state = ensureVisibleOnSomeDisplay(restore()) - - const win = new BrowserWindow({ - ...state, - ...options, - webPreferences: { - nodeIntegration: false, - contextIsolation: true, - ...options.webPreferences, - }, - }) - - win.on('close', saveState) - - return win -} diff --git a/examples/basic-js-python/main/helpers/index.js b/examples/basic-js-python/main/helpers/index.js deleted file mode 100644 index e1b9aad0..00000000 --- a/examples/basic-js-python/main/helpers/index.js +++ /dev/null @@ -1 +0,0 @@ -export * from './create-window' diff --git a/examples/basic-js-python/main/preload.js b/examples/basic-js-python/main/preload.js deleted file mode 100644 index 78349942..00000000 --- a/examples/basic-js-python/main/preload.js +++ /dev/null @@ -1,17 +0,0 @@ -import { contextBridge, ipcRenderer } from 'electron' - -const handler = { - send(channel, value) { - ipcRenderer.send(channel, value) - }, - on(channel, callback) { - const subscription = (_event, ...args) => callback(...args) - ipcRenderer.on(channel, subscription) - - return () => { - ipcRenderer.removeListener(channel, subscription) - } - }, -} - -contextBridge.exposeInMainWorld('ipc', handler) From 34388f66765f9527598289de239c7d583753451f Mon Sep 17 00:00:00 2001 From: Shiono Yoshihide Date: Sat, 3 Feb 2024 16:58:35 +0900 Subject: [PATCH 07/12] chore: Remove unused code --- examples/basic-js-python/main/background.js | 60 ++++++++------------- 1 file changed, 22 insertions(+), 38 deletions(-) diff --git a/examples/basic-js-python/main/background.js b/examples/basic-js-python/main/background.js index f98cb893..a9dd4371 100644 --- a/examples/basic-js-python/main/background.js +++ b/examples/basic-js-python/main/background.js @@ -1,57 +1,48 @@ -import { app, ipcMain } from 'electron'; +import path from 'path' +import { exec } from 'child_process' +import { app, ipcMain } from 'electron' import serve from 'electron-serve' import { createWindow } from './helpers' -const { exec } = require('child_process'); -const os = require('os'); -const path = require('path'); const isProd = process.env.NODE_ENV === 'production' -function resolveHome(filepath) { - if (filepath.startsWith('~')) { - return path.join(os.homedir(), filepath.slice(1)); - } - return filepath; -} - async function startProcess(event, value) { - if(event) { + if (event) { /* 'parentDir' is used to get this folder -> /Applications/.app/Contents/ so that we can run our .sh file which will also launch the Python or Rust script. So the script folder will be moved into parentDir/ in prod mode. Note: this will only work if the target mahcine have Python or Rust installed. - */ - let scriptPath - if (isProd) { - const parentDir = path.dirname(path.dirname(path.dirname(__dirname))) - scriptPath = path.join(parentDir, 'scripts/runner.sh'); - } else { - scriptPath = path.join(__dirname, '../scripts/runner.sh'); + */ + let scriptPath + if (isProd) { + const parentDir = path.dirname(path.dirname(path.dirname(__dirname))) + scriptPath = path.join(parentDir, 'scripts/runner.sh') + } else { + scriptPath = path.join(__dirname, '../scripts/runner.sh') } // console.log(`DEBUG: scriptPath: ${scriptPath}`) const cmd = `sh ${scriptPath} ${value}` - exec(cmd, (error, stdout, stderr) => { + exec(cmd, (error, stdout) => { if (error) { - console.error(`ERROR: Error executing post-install script: ${error}`); // will be seen only dev mode, not in prod mode - event.sender.send("log", error.message); // will be seen in both dev and prod mode (in the frontend) - return; + console.error(`ERROR: Error executing post-install script: ${error}`) // will be seen only dev mode, not in prod mode + event.sender.send('log', error.message) // will be seen in both dev and prod mode (in the frontend) + return } - event.sender.send("log", "Python script executed successfully"); - event.sender.send("message", stdout); - }); + event.sender.send('log', 'Python script executed successfully') + event.sender.send('message', stdout) + }) // ~/.yourApp.log will be helpfull to log process in production mode } } ipcMain.on('run-sh', async (event, value) => { - console.log("DEBUG: starting process") // for dev mode - event.sender.send("log", "Running...") // for prod mode - await startProcess(event, value); - } -); + console.log('DEBUG: starting process') // for dev mode + event.sender.send('log', 'Running...') // for prod mode + await startProcess(event, value) +}) if (isProd) { serve({ directory: 'app' }) @@ -59,7 +50,6 @@ if (isProd) { app.setPath('userData', `${app.getPath('userData')} (development)`) } - ;(async () => { await app.whenReady() @@ -83,9 +73,3 @@ if (isProd) { app.on('window-all-closed', () => { app.quit() }) - -// ipcMain.on('message', async (event, arg) => { -// event.reply('message', `${arg} World!`) -// }) - - From 3ed0e102b5bc94796261c70edc1435a868da83dd Mon Sep 17 00:00:00 2001 From: Shiono Yoshihide Date: Sat, 3 Feb 2024 16:59:49 +0900 Subject: [PATCH 08/12] chore: lint and format --- examples/basic-js-python/renderer/pages/home.jsx | 14 +++++++------- examples/basic-js-python/scripts/main.py | 3 +-- examples/basic-js-python/scripts/runner.sh | 2 +- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/examples/basic-js-python/renderer/pages/home.jsx b/examples/basic-js-python/renderer/pages/home.jsx index 72f49da7..f2a8d496 100644 --- a/examples/basic-js-python/renderer/pages/home.jsx +++ b/examples/basic-js-python/renderer/pages/home.jsx @@ -6,11 +6,11 @@ import Image from 'next/image' export default function HomePage() { const [log, setLog] = React.useState('') const [value, setValue] = React.useState('5') - const [message, setMessage] = React.useState("") + const [message, setMessage] = React.useState('') const handleChange = (event) => { setValue(event.target.value) - setMessage("") + setMessage('') } React.useEffect(() => { @@ -42,10 +42,9 @@ export default function HomePage() { />

- -

+

Calculate the sqaure of your number: - +

{log}

-

the square of {value} is {"-> "} {message}

- +

+ the square of {value} is {'-> '} {message} +

) diff --git a/examples/basic-js-python/scripts/main.py b/examples/basic-js-python/scripts/main.py index 31aee9a2..e06d2c4a 100644 --- a/examples/basic-js-python/scripts/main.py +++ b/examples/basic-js-python/scripts/main.py @@ -2,8 +2,7 @@ def square_of_number(): # time.sleep(3) # Simulate a long running process :), you can comment this line to have RT - print( int(sys.argv[1]) ** 2 ) + print(int(sys.argv[1]) ** 2) if __name__ == "__main__": square_of_number() - diff --git a/examples/basic-js-python/scripts/runner.sh b/examples/basic-js-python/scripts/runner.sh index 3bdc159e..b9596381 100644 --- a/examples/basic-js-python/scripts/runner.sh +++ b/examples/basic-js-python/scripts/runner.sh @@ -5,4 +5,4 @@ script_dir="$(dirname "$0")" cd $script_dir || exit 1 # cd to the script directory or exit if failed # run the app and pass the second argument to the app -echo $(python main.py $1) \ No newline at end of file +echo $(python main.py $1) From 6706c0f43d31794d0a39cd44715ad224e1bbb803 Mon Sep 17 00:00:00 2001 From: Shiono Yoshihide Date: Sat, 3 Feb 2024 17:45:50 +0900 Subject: [PATCH 09/12] fix: Control spaces in shell script --- examples/basic-js-python/main/background.js | 2 +- examples/basic-js-python/scripts/runner.sh | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/examples/basic-js-python/main/background.js b/examples/basic-js-python/main/background.js index a9dd4371..98132be7 100644 --- a/examples/basic-js-python/main/background.js +++ b/examples/basic-js-python/main/background.js @@ -22,7 +22,7 @@ async function startProcess(event, value) { scriptPath = path.join(__dirname, '../scripts/runner.sh') } // console.log(`DEBUG: scriptPath: ${scriptPath}`) - const cmd = `sh ${scriptPath} ${value}` + const cmd = `sh "${scriptPath}" ${value}` exec(cmd, (error, stdout) => { if (error) { diff --git a/examples/basic-js-python/scripts/runner.sh b/examples/basic-js-python/scripts/runner.sh index b9596381..3be934a9 100644 --- a/examples/basic-js-python/scripts/runner.sh +++ b/examples/basic-js-python/scripts/runner.sh @@ -1,8 +1,6 @@ #!/bin/sh -# get the directory of the script -script_dir="$(dirname "$0")" -cd $script_dir || exit 1 # cd to the script directory or exit if failed +cd "$(dirname "$0")" || exit 1 # cd to the script directory or exit if failed # run the app and pass the second argument to the app echo $(python main.py $1) From fd2f279f995b1ea89ce0704319c6e64f345b203e Mon Sep 17 00:00:00 2001 From: Shiono Yoshihide Date: Sat, 3 Feb 2024 17:46:22 +0900 Subject: [PATCH 10/12] refactor: Use electron-builder.yml instead of package.json#build property --- examples/basic-js-python/electron-builder.yml | 2 ++ examples/basic-js-python/package.json | 9 --------- 2 files changed, 2 insertions(+), 9 deletions(-) diff --git a/examples/basic-js-python/electron-builder.yml b/examples/basic-js-python/electron-builder.yml index 1b5a3bbe..eaae8ab3 100644 --- a/examples/basic-js-python/electron-builder.yml +++ b/examples/basic-js-python/electron-builder.yml @@ -9,4 +9,6 @@ files: filter: - package.json - app +extraFiles: + - scripts publish: null diff --git a/examples/basic-js-python/package.json b/examples/basic-js-python/package.json index 74936a2a..12b20c1e 100644 --- a/examples/basic-js-python/package.json +++ b/examples/basic-js-python/package.json @@ -10,15 +10,6 @@ "build": "nextron build", "postinstall": "electron-builder install-app-deps" }, - "build": { - "extraFiles": [ - { - "from": "scripts/", - "to": "scripts/", - "filter": "**/*" - } - ] - }, "dependencies": { "electron-serve": "^1.1.0", "electron-store": "^8.1.0" From 75b51234619dc8f4c4281e02407928511ed05506 Mon Sep 17 00:00:00 2001 From: Shiono Yoshihide Date: Sat, 3 Feb 2024 17:48:34 +0900 Subject: [PATCH 11/12] refactor: Rename (basic-js-python => basic-lang-javascript-python) --- .../README.md | 6 +++--- .../electron-builder.yml | 0 .../main/background.js | 0 .../package.json | 0 .../renderer/next.config.js | 0 .../renderer/pages/home.jsx | 2 +- .../renderer/pages/next.jsx | 2 +- .../scripts/main.py | 0 .../scripts/runner.sh | 0 9 files changed, 5 insertions(+), 5 deletions(-) rename examples/{basic-js-python => basic-lang-javascript-python}/README.md (86%) rename examples/{basic-js-python => basic-lang-javascript-python}/electron-builder.yml (100%) rename examples/{basic-js-python => basic-lang-javascript-python}/main/background.js (100%) rename examples/{basic-js-python => basic-lang-javascript-python}/package.json (100%) rename examples/{basic-js-python => basic-lang-javascript-python}/renderer/next.config.js (100%) rename examples/{basic-js-python => basic-lang-javascript-python}/renderer/pages/home.jsx (95%) rename examples/{basic-js-python => basic-lang-javascript-python}/renderer/pages/next.jsx (84%) rename examples/{basic-js-python => basic-lang-javascript-python}/scripts/main.py (100%) rename examples/{basic-js-python => basic-lang-javascript-python}/scripts/runner.sh (100%) diff --git a/examples/basic-js-python/README.md b/examples/basic-lang-javascript-python/README.md similarity index 86% rename from examples/basic-js-python/README.md rename to examples/basic-lang-javascript-python/README.md index cf2b23a8..04233fde 100644 --- a/examples/basic-js-python/README.md +++ b/examples/basic-lang-javascript-python/README.md @@ -6,13 +6,13 @@ ``` # with npx -$ npx create-nextron-app my-app --example basic-lang-javascript +$ npx create-nextron-app my-app --example basic-lang-javascript-python # with yarn -$ yarn create nextron-app my-app --example basic-lang-javascript +$ yarn create nextron-app my-app --example basic-lang-javascript-python # with pnpm -$ pnpm dlx create-nextron-app my-app --example basic-lang-javascript +$ pnpm dlx create-nextron-app my-app --example basic-lang-javascript-python ``` ### Install Dependencies diff --git a/examples/basic-js-python/electron-builder.yml b/examples/basic-lang-javascript-python/electron-builder.yml similarity index 100% rename from examples/basic-js-python/electron-builder.yml rename to examples/basic-lang-javascript-python/electron-builder.yml diff --git a/examples/basic-js-python/main/background.js b/examples/basic-lang-javascript-python/main/background.js similarity index 100% rename from examples/basic-js-python/main/background.js rename to examples/basic-lang-javascript-python/main/background.js diff --git a/examples/basic-js-python/package.json b/examples/basic-lang-javascript-python/package.json similarity index 100% rename from examples/basic-js-python/package.json rename to examples/basic-lang-javascript-python/package.json diff --git a/examples/basic-js-python/renderer/next.config.js b/examples/basic-lang-javascript-python/renderer/next.config.js similarity index 100% rename from examples/basic-js-python/renderer/next.config.js rename to examples/basic-lang-javascript-python/renderer/next.config.js diff --git a/examples/basic-js-python/renderer/pages/home.jsx b/examples/basic-lang-javascript-python/renderer/pages/home.jsx similarity index 95% rename from examples/basic-js-python/renderer/pages/home.jsx rename to examples/basic-lang-javascript-python/renderer/pages/home.jsx index f2a8d496..98670850 100644 --- a/examples/basic-js-python/renderer/pages/home.jsx +++ b/examples/basic-lang-javascript-python/renderer/pages/home.jsx @@ -25,7 +25,7 @@ export default function HomePage() { return ( - Home - Nextron (basic-js-python) + Home - Nextron (basic-lang-javascript-python)

diff --git a/examples/basic-js-python/renderer/pages/next.jsx b/examples/basic-lang-javascript-python/renderer/pages/next.jsx similarity index 84% rename from examples/basic-js-python/renderer/pages/next.jsx rename to examples/basic-lang-javascript-python/renderer/pages/next.jsx index 0d2d67c2..d102e0bf 100644 --- a/examples/basic-js-python/renderer/pages/next.jsx +++ b/examples/basic-lang-javascript-python/renderer/pages/next.jsx @@ -6,7 +6,7 @@ export default function NextPage() { return ( - Next - Nextron (basic-js-python) + Next - Nextron (basic-lang-javascript-python)

diff --git a/examples/basic-js-python/scripts/main.py b/examples/basic-lang-javascript-python/scripts/main.py similarity index 100% rename from examples/basic-js-python/scripts/main.py rename to examples/basic-lang-javascript-python/scripts/main.py diff --git a/examples/basic-js-python/scripts/runner.sh b/examples/basic-lang-javascript-python/scripts/runner.sh similarity index 100% rename from examples/basic-js-python/scripts/runner.sh rename to examples/basic-lang-javascript-python/scripts/runner.sh From 3094b2a8484f4e6d35325ad96a46856e5f12dca6 Mon Sep 17 00:00:00 2001 From: Shiono Yoshihide Date: Sat, 3 Feb 2024 17:57:17 +0900 Subject: [PATCH 12/12] chore(docs): Update README --- README.md | 19 +++++++++++++++++-- .../basic-lang-javascript-python/README.md | 2 +- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index a01d17e8..ef99c7ed 100644 --- a/README.md +++ b/README.md @@ -13,8 +13,8 @@

- - 2023 Roadmaps - I'm back! + + 2024 Roadmaps - I'm back!

@@ -259,6 +259,21 @@ $ yarn create nextron-app my-app --example basic-lang-javascript $ pnpm dlx create-nextron-app my-app --example basic-lang-javascript ``` +### [examples/basic-lang-javascript-python](./examples/basic-lang-javascript-python) + +

+ +``` +# with npx +$ npx create-nextron-app my-app --example basic-lang-javascript-python + +# with yarn +$ yarn create nextron-app my-app --example basic-lang-javascript-python + +# with pnpm +$ pnpm dlx create-nextron-app my-app --example basic-lang-javascript-python +``` + ### [examples/basic-lang-typescript](./examples/basic-lang-typescript)

diff --git a/examples/basic-lang-javascript-python/README.md b/examples/basic-lang-javascript-python/README.md index 04233fde..436d0539 100644 --- a/examples/basic-lang-javascript-python/README.md +++ b/examples/basic-lang-javascript-python/README.md @@ -1,4 +1,4 @@ -

+

## Usage