electron integration

This commit is contained in:
Richard Unger
2024-01-27 15:41:39 +01:00
parent 96b305b74d
commit e2f89c0ed3
15 changed files with 12493 additions and 8263 deletions

BIN
.vite/build/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

5
.vite/build/main.js Normal file

File diff suppressed because one or more lines are too long

1
.vite/build/preload.js Normal file
View File

@@ -0,0 +1 @@
"use strict";

View File

@@ -1,29 +1,16 @@
# zeroone # zeroone
This template should help get you started developing with Vue 3 in Vite. Haptic configuration utility
## Recommended IDE Setup ## Running the code
[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur) + [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin). - use VSCode
- run `sudo npm -g json-server`
- run `npm install`
- in another terminal, run `json-server --watch src/data/nanoConfig.json --port 3001`
- run `npm start`
## Customize configuration ## Connecting your Nano
See [Vite Configuration Reference](https://vitejs.dev/config/). TODO
## Project Setup
```sh
npm install
```
### Compile and Hot-Reload for Development
```sh
npm run dev
```
### Compile and Minify for Production
```sh
npm run build
```

48
forge.config.js Normal file
View File

@@ -0,0 +1,48 @@
module.exports = {
packagerConfig: {},
rebuildConfig: {},
makers: [
{
name: '@electron-forge/maker-squirrel',
config: {},
},
{
name: '@electron-forge/maker-zip',
platforms: ['darwin'],
},
{
name: '@electron-forge/maker-deb',
config: {},
},
{
name: '@electron-forge/maker-rpm',
config: {},
},
],
plugins: [
{
name: '@electron-forge/plugin-vite',
config: {
// `build` can specify multiple entry builds, which can be Main process, Preload scripts, Worker process, etc.
// If you are familiar with Vite configuration, it will look really familiar.
build: [
{
// `entry` is just an alias for `build.lib.entry` in the corresponding file of `config`.
entry: 'src/main.js',
config: 'vite.main.config.mjs',
},
{
entry: 'src/preload.js',
config: 'vite.preload.config.mjs',
},
],
renderer: [
{
name: 'main_window',
config: 'vite.renderer.config.mjs',
},
],
},
},
],
};

View File

@@ -8,6 +8,6 @@
</head> </head>
<body class="dark bg-background"> <body class="dark bg-background">
<div id="app"></div> <div id="app"></div>
<script type="module" src="/src/main.js"></script> <script type="module" src="/src/renderer.js"></script>
</body> </body>
</html> </html>

20437
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,18 +1,18 @@
{ {
"name": "zeroone", "name": "zeroone",
"version": "0.1.1", "version": "0.1.1",
"description": "Haptic configuration tool",
"private": true, "private": true,
"main": ".vite/build/main.js",
"XXtype": "module",
"XXmain": "background.js",
"scripts": { "scripts": {
"build": "vite build", "start": "electron-forge start",
"dev": "vite", "package": "electron-forge package",
"electron:build": "vue-cli-service electron:build", "make": "electron-forge make",
"electron:serve": "vue-cli-service electron:serve", "publish": "electron-forge publish",
"postinstall": "electron-builder install-app-deps", "lint": "echo \"No linting configured\""
"postuninstall": "electron-builder install-app-deps",
"preview": "vite preview",
"serve": "concurrently \"json-server src/data/nanoConfig.json --port=3001\" \"vite\" "
}, },
"main": "background.js",
"dependencies": { "dependencies": {
"@radix-icons/vue": "^1.0.0", "@radix-icons/vue": "^1.0.0",
"@radix-ui/react-icons": "^1.3.0", "@radix-ui/react-icons": "^1.3.0",
@@ -25,31 +25,37 @@
"clsx": "^2.1.0", "clsx": "^2.1.0",
"color": "^4.2.3", "color": "^4.2.3",
"concurrently": "^8.2.2", "concurrently": "^8.2.2",
"electron-squirrel-startup": "^1.0.0",
"lucide-vue-next": "^0.309.0", "lucide-vue-next": "^0.309.0",
"radix-vue": "^1.3.0", "radix-vue": "^1.3.0",
"tailwind-merge": "^2.2.0", "tailwind-merge": "^2.2.0",
"tailwindcss-animate": "^1.0.7", "tailwindcss-animate": "^1.0.7",
"vee-validate": "^4.12.4", "vee-validate": "^4.12.4",
"vue": "^3.3.11", "vue": "^3.4.15",
"vue-i18n": "^9.9.0", "vue-i18n": "^9.9.0",
"zod": "^3.22.4" "zod": "^3.22.4"
}, },
"devDependencies": { "devDependencies": {
"@electron-forge/cli": "^7.2.0",
"@electron-forge/maker-deb": "^7.2.0",
"@electron-forge/maker-rpm": "^7.2.0",
"@electron-forge/maker-squirrel": "^7.2.0",
"@electron-forge/maker-zip": "^7.2.0",
"@electron-forge/plugin-auto-unpack-natives": "^7.2.0",
"@electron-forge/plugin-vite": "^7.2.0",
"@intlify/eslint-plugin-vue-i18n": "^2.0.0", "@intlify/eslint-plugin-vue-i18n": "^2.0.0",
"@types/node": "^20.11.0", "@types/node": "^20.11.0",
"@vitejs/plugin-vue": "^4.5.2", "@vitejs/plugin-vue": "^5.0.3",
"autoprefixer": "^10.4.16", "autoprefixer": "^10.4.17",
"electron": "^13.0.0", "electron": "28.2.0",
"electron-devtools-installer": "^3.1.0",
"eslint": "^8.56.0", "eslint": "^8.56.0",
"eslint-config-prettier": "^9.1.0", "eslint-config-prettier": "^9.1.0",
"eslint-plugin-vue": "^9.20.1", "eslint-plugin-vue": "^9.20.1",
"json-server": "^1.0.0-alpha.21", "json-server": "^1.0.0-alpha.21",
"postcss": "^8.4.33", "postcss": "^8.4.33",
"postcss-loader": "^8.0.0",
"prettier": "3.2.4", "prettier": "3.2.4",
"tailwindcss": "^3.4.1", "tailwindcss": "^3.4.1"
"vite": "^5.0.10",
"vue-cli-plugin-electron-builder": "~2.1.1"
}, },
"eslintConfig": { "eslintConfig": {
"root": true, "root": true,
@@ -105,6 +111,5 @@
"semi": false, "semi": false,
"singleQuote": true "singleQuote": true
}, },
"type": "module",
"web-types": "./web-types.json" "web-types": "./web-types.json"
} }

View File

@@ -1,4 +1,4 @@
export default { module.exports = {
plugins: { plugins: {
tailwindcss: {}, tailwindcss: {},
autoprefixer: {}, autoprefixer: {},

View File

@@ -1,48 +1,54 @@
import './assets/main.css' import { app, BrowserWindow } from 'electron';
import Axios from 'axios' import path from 'path';
import 'electron-squirrel-startup';
import { createApp } from 'vue' // TODO Handle creating/removing shortcuts on Windows when installing/uninstalling.
import { createI18n } from 'vue-i18n' //if (require('electron-squirrel-startup')) {
// app.quit();
//}
import en from '@/lang/en.json' const createWindow = () => {
// Create the browser window.
const mainWindow = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
preload: path.join(__dirname, 'preload.js'),
},
});
import App from '@/App.vue' // and load the index.html of the app.
if (MAIN_WINDOW_VITE_DEV_SERVER_URL) {
mainWindow.loadURL(MAIN_WINDOW_VITE_DEV_SERVER_URL);
} else {
mainWindow.loadFile(path.join(__dirname, `../renderer/${MAIN_WINDOW_VITE_NAME}/index.html`));
}
import { store } from '@/store.js' // Open the DevTools.
mainWindow.webContents.openDevTools();
};
import Ajv from 'ajv' // This method will be called when Electron has finished
import schema from '@/data/profileSchema.json' // initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.on('ready', createWindow);
const ajv = new Ajv() // Quit when all windows are closed, except on macOS. There, it's common
// for applications and their menu bar to stay active until the user quits
// explicitly with Cmd + Q.
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit();
}
});
Axios.get('http://localhost:3001/profiles').then((res) => { app.on('activate', () => {
const profiles = res.data // On OS X it's common to re-create a window in the app when the
console.log(profiles) // dock icon is clicked and there are no other windows open.
const ids = new Set() if (BrowserWindow.getAllWindows().length === 0) {
const validate = ajv.compile(schema) createWindow();
store.device.profiles = profiles.filter((profile) => { }
if (!validate(profile)) { });
console.error('Failed to validate profile: ' + profile.name, validate.errors)
return false
}
if (ids.has(profile.id)) {
console.error('Duplicate profile id: ' + profile.id + ' for profile: ' + profile.name)
return false
}
ids.add(profile.id)
return true
})
}).catch((err) => {
console.error(err)
})
// Create VueI18n instance with locales loaded from /lang directory // In this file you can include the rest of your app's specific main process
const i18n = createI18n({ // code. You can also put them in separate files and import them here.
locale: 'en',
fallbackLocale: 'en',
messages: { en: en },
})
const app = createApp(App)
app.use(i18n)
app.mount('#app')

2
src/preload.js Normal file
View File

@@ -0,0 +1,2 @@
// See the Electron documentation for details on how to use preload scripts:
// https://www.electronjs.org/docs/latest/tutorial/process-model#preload-scripts

74
src/renderer.js Normal file
View File

@@ -0,0 +1,74 @@
/**
* This file will automatically be loaded by vite and run in the "renderer" context.
* To learn more about the differences between the "main" and the "renderer" context in
* Electron, visit:
*
* https://electronjs.org/docs/tutorial/application-architecture#main-and-renderer-processes
*
* By default, Node.js integration in this file is disabled. When enabling Node.js integration
* in a renderer process, please be aware of potential security implications. You can read
* more about security risks here:
*
* https://electronjs.org/docs/tutorial/security
*
* To enable Node.js integration in this file, open up `main.js` and enable the `nodeIntegration`
* flag:
*
* ```
* // Create the browser window.
* mainWindow = new BrowserWindow({
* width: 800,
* height: 600,
* webPreferences: {
* nodeIntegration: true
* }
* });
* ```
*/
import { createApp } from 'vue';
import { createI18n } from 'vue-i18n'
import App from './App.vue'
import en from '@/lang/en.json'
import './assets/index.css'
import { store } from '@/store.js'
import Ajv from 'ajv'
import schema from '@/data/profileSchema.json'
import Axios from 'axios'
const ajv = new Ajv()
Axios.get('http://localhost:3001/profiles').then((res) => {
const profiles = res.data
console.log(profiles)
const ids = new Set()
const validate = ajv.compile(schema)
store.device.profiles = profiles.filter((profile) => {
if (!validate(profile)) {
console.error('Failed to validate profile: ' + profile.name, validate.errors)
return false
}
if (ids.has(profile.id)) {
console.error('Duplicate profile id: ' + profile.id + ' for profile: ' + profile.name)
return false
}
ids.add(profile.id)
return true
})
}).catch((err) => {
console.error(err)
})
// Create VueI18n instance with locales loaded from /lang directory
const i18n = createI18n({
locale: 'en',
fallbackLocale: 'en',
messages: { en: en },
});
const app = createApp(App);
app.use(i18n)
app.mount('#app');

11
vite.main.config.mjs Normal file
View File

@@ -0,0 +1,11 @@
import { defineConfig } from 'vite';
// https://vitejs.dev/config
export default defineConfig({
resolve: {
// Some libs that can run in both Web and Node.js, such as `axios`, we need to tell Vite to build them in Node.js.
browserField: false,
conditions: ['node'],
mainFields: ['module', 'jsnext:main', 'jsnext'],
},
});

4
vite.preload.config.mjs Normal file
View File

@@ -0,0 +1,4 @@
import { defineConfig } from 'vite';
// https://vitejs.dev/config
export default defineConfig({});

View File

@@ -1,16 +1,12 @@
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
import { fileURLToPath, URL } from 'node:url' import { fileURLToPath, URL } from 'node:url'
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
// https://vitejs.dev/config/
export default defineConfig({ export default defineConfig({
plugins: [ plugins: [vue()],
vue(),
],
resolve: { resolve: {
alias: { alias: {
'@': fileURLToPath(new URL('./src', import.meta.url)) '@': fileURLToPath(new URL('./src', import.meta.url))
} }
} }
}) });