Skip to content

Commit

Permalink
feat: Add Electron support for desktop app (#3)
Browse files Browse the repository at this point in the history
  • Loading branch information
sammcj authored Jul 22, 2024
1 parent 39da914 commit deb2cbd
Show file tree
Hide file tree
Showing 15 changed files with 3,020 additions and 1,944 deletions.
59 changes: 59 additions & 0 deletions .github/workflows/build-app.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
name: Build and Release Electron App

on:
workflow_dispatch:

permissions:
contents: read
packages: write

jobs:
build:
runs-on: ubuntu-latest

strategy:
matrix:
os: [macos-latest, ubuntu-latest]

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: '22'

- name: Install dependencies
run: npm i

- name: Build app
run: npm run build

- name: Package Electron app
run: npm run electron-pack

- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: app
path: dist/

release:
needs: build
runs-on: ubuntu-latest

steps:
- name: Download artifact
uses: actions/download-artifact@v4
with:
name: app
path: dist/

- name: Create GitHub Release
uses: ncipollo/release-action@v1
with:
artifacts: "dist/*"
draft: true
makeLatest: true
token: ${{ secrets.GITHUB_TOKEN }}
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,7 @@ yarn-error.log*
# typescript
*.tsbuildinfo
next-env.d.ts

# Electron build artifacts
/dist/
*.asar
17 changes: 17 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,23 @@ Note you can optionally set the environment variable `OPENAI_API_BASE` before la
OPENAI_API_BASE=http://localhost:11434/v1 pnpm start
```

## Build Desktop App

To build the desktop app, you need to have `electron` and `electron-builder` installed as dependencies. The `package.json` file has been updated to include these dependencies and the necessary build scripts.

```bash
pnpm install
pnpm run electron-pack
```

## Run Desktop App

To run the desktop app in development mode, use the following command:

```bash
pnpm run electron-dev
```

## Acknowledgements

- [rooben-me](https://github.com/rooben-me/tone-changer-open)
Expand Down
2 changes: 1 addition & 1 deletion components.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,4 @@
"components": "@/components",
"utils": "@/lib/utils"
}
}
}
12 changes: 10 additions & 2 deletions components/commons/Footer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,16 @@ import Image from "next/image";
import Link from "next/link";
import LinkedInIcon from "../Icons/LinkedInIcon";
import GitHubIcon from "../Icons/GithubIcon";

declare global {
interface Window {
electronAPI: {
getAssetPath: (assetName: string) => string;
};
}
}
const Footer = () => {
const avatarSrc = 'avatar.webp';

return (
<footer>
<div className="flex flex-col gap-4 items-center justify-center mt-24 mb-24 lg:mb-0">
Expand All @@ -15,7 +23,7 @@ const Footer = () => {
className="flex items-center gap-2 px-4 py-2 rounded-lg bg-orange-900/10 border border-orange-800/30 text-orange-400 grayscale hover:grayscale-0 ease-in-out transition-all backdrop-blur-md"
>
<div className="-ml-2">
<Image src="/avatar.webp" width={24} height={24} alt="" />
<Image src={avatarSrc} width={24} height={24} alt="" />
</div>
My Blog
</Link>
Expand Down
2 changes: 1 addition & 1 deletion components/commons/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ const Header = () => {
return (
<header className="mb-2 flex flex-col items-center lg:flex-row lg:justify-between gap-4">
<div className="flex items-center gap-4">
<Image src="/logo.png" width={50} height={50} alt="" />
<Image src="logo.png" width={50} height={50} alt="" />
<h1 className="text-4xl md:text-4xl font-extrabold text-indigo-300 lg:text-left bg-gradient-to-t from-indigo-900 via-indigo-500 to-indigo-400 inline-block text-transparent bg-clip-text text-center py-1">
LLM Parameter Playground
</h1>
Expand Down
14 changes: 1 addition & 13 deletions components/commons/Setting.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ const Setting = () => {
});
} catch (error) {
toast.error("Failed to fetch models", {
description: "Please check your API URL and try again.",
description: "Please check your API URL and try again, error: " + error,
});
} finally {
setIsFetchingModels(false);
Expand Down Expand Up @@ -167,18 +167,6 @@ const Setting = () => {
)}
</button>
</div>
<p className="text-xs text-gray-400 mt-2">
Need an API key? Visit{" "}
<a
href="https://console.groq.com/docs/quickstart"
target="_blank"
rel="noopener noreferrer"
className="text-purple-400 hover:underline"
>
Groq Console
</a>{" "}
to get a free API key
</p>
</div>


Expand Down
12 changes: 12 additions & 0 deletions entitlements.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.cs.allow-jit</key>
<true />
<key>com.apple.security.network.client</key>
<true />
<key>com.apple.security.network.server</key>
<true />
</dict>
</plist>
77 changes: 77 additions & 0 deletions main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
const { app, BrowserWindow } = require('electron');
const path = require('path');
const { title } = require('process');

function createWindow() {
const win = new BrowserWindow({
width: 1920,
height: 1640,
movable: true,
// frame: false,
icon: path.join(__dirname, 'assets/icon.png'),
zoomToPageWidth: true,
title: 'LLM Parameter Playground',
minWidth: 1660,
minHeight: 1080,
roundedCorners: true,
webPreferences: {
preload: path.join(__dirname, 'preload.js'),
nodeIntegration: true,
nodeIntegrationInWorker: true,
contextIsolation: true,
webSecurity: true
}
});

const startUrl = `file://${path.join(app.getAppPath(), 'out/index.html')}`;

win.loadURL(startUrl);

// Enable devtools
// win.webContents.openDevTools();

win.once('ready-to-show', () => {
win.show()
})

}

const { session } = require('electron')

app.whenReady().then(() => {
// allow all cors
session.defaultSession.webRequest.onBeforeSendHeaders((details, callback) => {
details.requestHeaders['Origin'] = '*';
callback({ requestHeaders: details.requestHeaders });
});


session.defaultSession.webRequest.onHeadersReceived((details, callback) => {
if (details.responseHeaders) {
details.responseHeaders['Access-Control-Allow-Origin'] = ['*'];
}
callback({ responseHeaders: details.responseHeaders });
});

createWindow();
});

app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit();
}
});

app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow();
}
});

// improve performance of first launch by caching the app
app.commandLine.appendSwitch('js-flags', '--no-lazy');

//hot reload
try {
require('electron-reloader')(module)
} catch (_) { }
13 changes: 7 additions & 6 deletions next.config.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// module.exports = {
// output: 'export',
// images: {
// unoptimized: true,
// },
// }
module.exports = {
output: 'export',
images: {
unoptimized: true,
},
assetPrefix: './',
}
35 changes: 32 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,17 @@
{
"private": true,
"name": "io.sammcj.llm-parameter-playground",
"version": "1.0.0",
"author": "Sam McLeod (@sammcj)",
"description": "A playground for exploring inference parameters with LLM models.",
"icon": "out/logo.png",
"homepage": "https://github.com/sammcj/parameter-playground",
"scripts": {
"dev": "next",
"build": "next build",
"start": "next start"
"start": "next start",
"electron-dev": "concurrently \"npm:dev\" \"node_modules/.bin/wait-on http://localhost:3000 && electron .\"",
"electron-pack": "pnpm run build && electron-builder --mac dir --config -c.mac.identity=null"
},
"dependencies": {
"@radix-ui/react-dialog": "^1.1.1",
Expand All @@ -14,25 +22,46 @@
"@radix-ui/react-switch": "1.1.0",
"class-variance-authority": "^0.7.0",
"clsx": "^2.1.1",
"concurrently": "^7.0.0",
"lodash": "^4.17.21",
"lucide-react": "^0.411.0",
"lucide-react": "^0.414.0",
"next": "^14.2.5",
"next-themes": "^0.3.0",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-spring": "^9.7.3",
"react-native": "^0.74.3",
"react-spring": "^9.7.4",
"sonner": "^1.5.0",
"tailwind-merge": "^2.4.0",
"tailwindcss-animate": "^1.0.7",
"use-scramble": "^2.2.15",
"wait-on": "^7.2.0",
"zustand": "^4.5.4"
},
"devDependencies": {
"@types/node": "20.14.11",
"@types/react": "18.3.3",
"autoprefixer": "^10.4.19",
"electron": "^31.2.1",
"electron-builder": "^24.13.3",
"electron-reloader": "^1.2.3",
"postcss": "^8.4.39",
"tailwindcss": "^3.4.6",
"typescript": "5.5.3"
},
"main": "main.js",
"build": {
"appId": "com.sammcj.llm-parameter-playground",
"mac": {
"category": "public.app-category.developer-tools",
"icon": "out/logo.png",
"target": "dir"
},
"linux": {
"target": "AppImage",
"category": "Development",
"icon": "out/logo.png",
"executableName": "llm-parameter-playground"
}
}
}
Loading

0 comments on commit deb2cbd

Please sign in to comment.