Skip to content

Commit f70fb8b

Browse files
committed
Embedded Express/Socket.io server into Electron helper app, added Webpack configuration for uxp plugin to handle dependencies
1 parent fb0e4f9 commit f70fb8b

22 files changed

+3540
-45
lines changed

desktop-helper-sample/README.md

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,65 @@
11
# Desktop Helper Example
22
This sample has two components, a Ps plugin and an Electron application built in React.
3+
34
For developers who have used `create-react-app` before, the folder structure and tools used in the Electron application will be familiar.
45

56
Both components must be running for the example to work correctly.
67

78
# Configuration
89
The following steps will help you load the plugin into Photoshop and get the Electron app up and running.
910

11+
## UXP Plugin
12+
13+
### 1. Install Node.js dependencies
14+
```
15+
$ cd uxp
16+
$ yarn install # or npm install
17+
```
18+
19+
### 2. Run plugin in watch or build mode
20+
```
21+
$ cd uxp
22+
$ yarn watch # or npm run watch
23+
24+
# OR
25+
26+
$ yarn build # or npm run build
27+
```
28+
29+
* `yarn watch` or `npm run watch` will build a development version of the plugin, and recompile everytime you make a change to the source files. The result is placed in `uxp/dist`.
30+
* `yarn build` or `npm run build` will build a production version of the plugin and place it in `uxp/dist`. It will not update every time you make a change to the source files.
31+
32+
> You **must** run either `watch` or `build` prior to trying to use within Photoshop!
33+
34+
## Electron Helper
35+
1036
### 1. Install Node.js dependencies
1137
```
1238
$ cd helper
1339
$ yarn install # or npm install
1440
```
1541

16-
### 2. Run Helper App
42+
### 2. Run helper app
1743
```
1844
$ cd helper
1945
$ yarn start
2046
```
2147

48+
### 3. (Optional) Build the helper app
49+
```
50+
$ cd helper
51+
$ yarn build
52+
```
53+
54+
**Warning:** This command will take quite some time to execute.
55+
56+
In Electron, production builds compile JavaScript into a binary executable on the target platform for distribution or personal use. It is recommended that you build for production when you finish development.
57+
58+
Once built, navigate to the `helper/dist` folder and double click the `UXP Helper App Setup 1.0.0` installer. Upon installation, the helper app can be run locally. Please note, the Electron project will have to be rebuilt and reinstalled for any future changes to take effect in production.
59+
2260
# Load the Plugin
23-
The plugin requires no dependencies and can be run by using the UXP Developer Tools. Click "Add Plugin..." in the UXP Developer Tools and select `plugin/manifest.json`, then click the ••• button and select "Load...".
61+
You can use the UXP Developer Tools to load the plugin into Photoshop.
62+
63+
If the plugin hasn't already been added to your workspace in the UXP Developer Tools, you can add it by clicking "Add Plugin..." and selecting `uxp/dist/manifest.json`. **DO NOT** select the `manifest.json` file inside the `uxp/plugin` folder.
64+
65+
Once added, you can load it into Photoshop by clicking the ••• button on the corresponding row, and clicking "Load". Switch to Photoshop and you should see the sample panel.

desktop-helper-sample/helper/package.json

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,22 +3,50 @@
33
"version": "1.0.0",
44
"license": "none",
55
"private": true,
6+
"main": "public/electron.js",
7+
"homepage": "./",
68
"scripts": {
79
"start": "concurrently -k \"npm run start:react\" \"npm run start:electron\"",
8-
"start:electron": "wait-on tcp:3000 && electron public/electron.js",
910
"start:react": "cross-env BROWSER=none react-scripts start",
10-
"build": "react-scripts build",
11+
"start:electron": "wait-on tcp:3000 && electron public/electron.js",
12+
"build": "npm run build:react && npm run build:electron",
13+
"build:react": "react-scripts build",
14+
"build:electron": "electron-builder",
1115
"eject": "react-scripts eject"
1216
},
1317
"devDependencies": {
1418
"concurrently": "^6.2.0",
19+
"cross-env": "^7.0.3",
1520
"electron": "^13.1.6",
21+
"electron-builder": "^22.11.7",
1622
"wait-on": "^6.0.0"
1723
},
1824
"dependencies": {
25+
"electron-is-dev": "^2.0.0",
26+
"express": "^4.17.1",
1927
"react": "^17.0.2",
2028
"react-dom": "^17.0.2",
21-
"react-scripts": "4.0.3"
29+
"react-scripts": "4.0.3",
30+
"socket.io": "^4.1.2"
31+
},
32+
"build": {
33+
"appId": "com.electron.adobe.example.desktop-helper-sample",
34+
"productName": "UXP Helper App",
35+
"mac": {
36+
"category": "public.app-category.developer-tools",
37+
"target": [
38+
"dmg"
39+
]
40+
},
41+
"win": {
42+
"asar": false,
43+
"target": [
44+
"nsis"
45+
]
46+
},
47+
"directories": {
48+
"output": "dist"
49+
}
2250
},
2351
"browserslist": {
2452
"production": [

desktop-helper-sample/helper/public/electron.js

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
11
const { app, BrowserWindow } = require('electron');
2+
const isDevelopment = require('electron-is-dev');
3+
const path = require('path');
4+
5+
require('./server.js');
26

37
const createWindow = () => {
48
const window = new BrowserWindow({
@@ -10,8 +14,15 @@ const createWindow = () => {
1014
});
1115

1216
// Configure electron development environment
13-
window.loadURL('http://localhost:3000');
14-
window.webContents.openDevTools({ mode: 'detach' });
17+
window.loadURL(isDevelopment
18+
? 'http://localhost:3000'
19+
: `file://${path.join(__dirname, '../build/index.html')}`);
20+
21+
if (isDevelopment) {
22+
window.webContents.openDevTools({
23+
mode: 'detach'
24+
});
25+
}
1526
};
1627

1728
app.whenReady().then(createWindow);
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
const http = require('http');
2+
const express = require('express');
3+
const { Server } = require('socket.io');
4+
5+
const startServer = async () => {
6+
const port = 4040;
7+
const app = express();
8+
const server = http.createServer(app);
9+
10+
const io = new Server(server);
11+
12+
server.listen(port, () => {
13+
console.log(`[server] Server listening on port ${port}`);
14+
});
15+
16+
io.on('connection', (socket) => {
17+
console.log('[socket.io] UXP plugin connected');
18+
19+
io.emit('uxp-connected', true);
20+
21+
socket.on('message', (message) => {
22+
console.log(`Message received from client: ${message}`);
23+
});
24+
25+
socket.on('disconnect', () => {
26+
console.log('[socket.io] UXP plugin disconnected');
27+
});
28+
});
29+
30+
// Emit connect when uxp attempts to reconnect
31+
io.on('reconnect', (socket) => {
32+
io.emit('uxp-connected', true);
33+
});
34+
35+
// Emit disconnect when helper app closes
36+
process.on('exit', () => {
37+
io.emit('uxp-connected', false);
38+
});
39+
};
40+
41+
startServer().catch((err) => {
42+
console.log(`[server] Error: ${err}`)
43+
});

desktop-helper-sample/helper/src/App.jsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import './App.css';
22

3-
function App() {
3+
const App = () => {
44
return (
55
<div className="container">
66
<header className="header">

0 commit comments

Comments
 (0)