Skip to content

Commit

Permalink
Feat: Basic app structure (#28)
Browse files Browse the repository at this point in the history
  • Loading branch information
Uninen authored Feb 15, 2022
1 parent e55073a commit d0a814c
Show file tree
Hide file tree
Showing 28 changed files with 811 additions and 198 deletions.
34 changes: 1 addition & 33 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -92,41 +92,9 @@ jobs:
node-version: 16 # Need for npm >=7.7
cache: 'npm'

## Yarn dir
- name: Get yarn cache directory path
id: yarn-cache-dir-path
run: echo "::set-output name=dir::$(yarn cache dir)"

## Cache
- name: Cache yarn cache
uses: actions/cache@v2
id: cache-yarn-cache2
with:
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
key: ${{ runner.os }}-yarn2-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
${{ runner.os }}-yarn2-
## Cache
- name: Cache node_modules
id: cache-node-modules2
uses: actions/cache@v2
with:
path: node_modules
key: ${{ runner.os }}-${{ matrix.node-version }}-nodemodules2-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
${{ runner.os }}-${{ matrix.node-version }}-nodemodules2-
- name: Download standalone Python
run: |
./downloadPython.sh
## Dependencies
- name: Install Dependencies
if: |
steps.cache-yarn-cache.outputs.cache-hit != 'true' ||
steps.cache-node-modules.outputs.cache-hit != 'true'
run: yarn --frozen-lockfile
- uses: bahmutov/npm-install@v1

# The easiest way to transfer release notes to a compiled application is create `release-notes.md` in the build resources.
# See https://github.com/electron-userland/electron-builder/issues/1511#issuecomment-310160119
Expand Down
50 changes: 3 additions & 47 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,58 +23,14 @@ jobs:
e2e:
strategy:
matrix:
os: [macos-latest]
os: [ubuntu-latest]

runs-on: ${{ matrix.os }}

steps:
- uses: actions/checkout@v2

## Yarn dir
- name: Get yarn cache directory path
id: yarn-cache-dir-path
run: echo "::set-output name=dir::$(yarn cache dir)"

## Cache
- name: Cache yarn cache
uses: actions/cache@v2
id: cache-yarn-cache2
with:
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
key: ${{ runner.os }}-yarn2-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
${{ runner.os }}-yarn2-
## Cache
- name: Cache node_modules
id: cache-node-modules2
uses: actions/cache@v2
with:
path: node_modules
key: ${{ runner.os }}-${{ matrix.node-version }}-nodemodules2-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
${{ runner.os }}-${{ matrix.node-version }}-nodemodules2-
- name: Configure pip caching
id: cache-pip
uses: actions/cache@v2
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}
restore-keys: |
${{ runner.os }}-pip-
- name: Download standalone Python
run: |
./downloadPython.sh
## Dependencies
- name: Install Dependencies
if: |
steps.cache-yarn-cache.outputs.cache-hit != 'true' ||
steps.cache-node-modules.outputs.cache-hit != 'true'
run: yarn --frozen-lockfile
- uses: bahmutov/npm-install@v1

## Test
- name: Run tests
run: yarn test
run: xvfb-run --auto-servernum --server-args="-screen 0 1280x960x24" -- npm run test
2 changes: 1 addition & 1 deletion .github/workflows/typechecking.yml
Original file line number Diff line number Diff line change
Expand Up @@ -63,4 +63,4 @@ jobs:
# Type checking is divided into three separate commands for more convenient logs
- run: yarn typecheck-main
- run: yarn typecheck-preload
- run: yarn typecheck-rendere
- run: yarn typecheck-renderer
22 changes: 17 additions & 5 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,28 @@
"version": "0.2.0",
"configurations": [
{
"name": "Debug Main Process",
"type": "node",
"request": "launch",
"cwd": "${workspaceFolder}",
"name": "Electron: Main",
"runtimeExecutable": "${workspaceFolder}/node_modules/.bin/electron",
"runtimeArgs": ["--remote-debugging-port=5858", "."],
"windows": {
"runtimeExecutable": "${workspaceFolder}/node_modules/.bin/electron.cmd"
},
"args": ["."],
"outputCapture": "std"
}
},
{
"name": "Electron: Renderer",
"type": "chrome",
"request": "attach",
"port": 5858,
"webRoot": "${workspaceFolder}",
"timeout": 30000
}
],
"compounds": [
{
"name": "Electron: All",
"configurations": ["Electron: Main", "Electron: Renderer"]
}
]
}
7 changes: 1 addition & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,10 @@
# Slipmat Soundboard

An opinionated template for running Python with Electron. Uses TypeScript, Vue 3, and Vite for bundling. Based on [vite-electron-builder](https://github.com/cawa-93/vite-electron-builder) by Alex Kozack and [datasette-app](https://github.com/simonw/datasette-app) by Simon Willison.

The JavaScript/TypeScript parts are configured to work as closely with Vue best practises, and they follow the same principles than my [vite-ts-tailwind-starter](https://github.com/Uninen/vite-ts-tailwind-starter).

Simple soundboard for DJs.
## Getting started

#### Install Dependencies

- Install wget: `brew install wget`
- Install Python: `./downloadPython`
- Install Electron dependencies: `yarn`

#### Start Development Environment
Expand Down
12 changes: 10 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,15 @@
"compilearm": "yarn build && SKIP_NOTARIZATION=1 electron-builder build --config .electron-builder.config.js --dir --config.asar=false --arm64",
"compilex64": "yarn build && SKIP_NOTARIZATION=1 electron-builder build --config .electron-builder.config.js --dir --config.asar=false --x64",
"pretest": "npm run build",
"test:ci": "xvfb-run tests/app.spec.js",
"test": "node tests/app.spec.js",
"watch": "node scripts/watch.js",
"dev": "yarn watch",
"lint": "eslint . --ext js,ts,vue",
"typecheck-main": "tsc --noEmit -p packages/main/tsconfig.json",
"typecheck-preload": "tsc --noEmit -p packages/preload/tsconfig.json",
"typecheck-rendere": "vue-tsc --noEmit -p packages/renderer/tsconfig.json",
"typecheck": "yarn typecheck-main && yarn typecheck-preload && yarn typecheck-rendere",
"typecheck-renderer": "vue-tsc --noEmit -p packages/renderer/tsconfig.json",
"typecheck": "yarn typecheck-main && yarn typecheck-preload && yarn typecheck-renderer",
"pretypecheck-renderer": "dts-cb -i packages/preload/src/**/*.ts -o packages/preload/exposedInMainWorld.d.ts"
},
"browserslist": [
Expand All @@ -37,14 +38,21 @@
"pre-push": "yarn typecheck"
},
"dependencies": {
"@nuxt/devalue": "^2.0.0",
"add-filename-increment": "^1.0.0",
"autoprefixer": "^10.4",
"electron-settings": "^4.0",
"electron-store": "^8.0.1",
"electron-updater": "^4.6",
"electron-util": "^0.17",
"events": "^3.3",
"pinia": "^2.0",
"postcss": "^8.4",
"postcss-import": "^14.0.2",
"rambda": "^7.0.2",
"tailwindcss": "^3.0",
"uniquefilename": "^1.1.2",
"unused-filename": "^4.0.0",
"v8-compile-cache": "^2.3.0",
"vue": "^3.2",
"vue-router": "^4.0"
Expand Down
101 changes: 94 additions & 7 deletions packages/main/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,46 @@
import { app, BrowserWindow } from 'electron'
import { app, BrowserWindow, ipcMain, dialog } from 'electron'
import { join } from 'path'
import { mkdir } from 'fs/promises'
import { URL } from 'url'
import { enforceApplicationFolder } from './utils'
// import 'v8-compile-cache'
// import devalue from '@nuxt/devalue'
import Store from 'electron-store'
import 'v8-compile-cache'

import {
enforceApplicationFolder,
pathAvailable,
filepathsToSamples,
} from './utils'
import './security'

// import settings from 'electron-settings'

// See https://www.electronjs.org/docs/latest/tutorial/offscreen-rendering
app.disableHardwareAcceleration()

const store = new Store({
name: 'pinia',
// serialize: devalue,
})
const isSingleInstance = app.requestSingleInstanceLock()
const userDataPath = app.getPath('userData')
const samplePath = join(userDataPath, 'samples')
console.log('userDataPath', userDataPath)
pathAvailable(samplePath).then((available) => {
if (available) {
mkdir(samplePath).then(() => {
console.log('Created sample folder')
})
}
})

const isDevelopment = import.meta.env.MODE === 'development'
const openDevtools = isDevelopment
// const openDevtools = true

// const prodDebug = import.meta.env.VITE_PROD_DEBUG === '1'
let mainWindow: BrowserWindow | null = null
let rendererReady = false
let mainWindow: BrowserWindow
const mainPageUrl =
isDevelopment && import.meta.env.VITE_DEV_SERVER_URL !== undefined
? import.meta.env.VITE_DEV_SERVER_URL
Expand All @@ -38,18 +65,78 @@ if (isDevelopment) {
.catch((e) => console.error('Failed to install Vue devtools extension:', e))
}

ipcMain.on('electron-store-get', async (event, val) => {
event.returnValue = store.get(val)
})
ipcMain.on('electron-store-set', async (event, key, val) => {
console.log('store set: ', val)
console.log('store set: ', typeof val)
store.set(key, val)
})

ipcMain.on('rendererReady', () => {
console.log('renderer is ready!')
rendererReady = true
})

ipcMain.on('openSamplesFilepicker', () => {
console.log('main -> openSamplesFilepicker')
// Opening file dialog more than once hangs without this
// https://github.com/electron/electron/issues/20533
const interval = setInterval(() => {
/* nothing */
}, 50)

dialog
.showOpenDialog({
filters: [{ name: 'Samples', extensions: ['mp3', 'wav', 'aac'] }],
properties: ['openFile', 'multiSelections'],
})
.then((result) => {
clearInterval(interval)
filepathsToSamples(samplePath, result.filePaths).then((samples) => {
console.log('got samples: ', samples)
mainWindow.webContents.send('addedSamples', samples)
})
})
.catch((err) => {
console.error('main -> openSamplesFilepicker CATCH', err)
// return reject(err)
})
})

function initMain() {
return new Promise<void>((resolve) => {
resolve()
})
}

const createWindow = async () => {
mainWindow = new BrowserWindow({
width: 800,
height: 600,
show: false, // Use 'ready-to-show' event to show window
titleBarStyle: 'hidden',
trafficLightPosition: { x: 18, y: 18 },
webPreferences: {
webviewTag: false,
nativeWindowOpen: true,
preload: join(__dirname, '../../preload/dist/index.cjs'),
},
})
mainWindow.setBackgroundColor('#1C1E20')

if (openDevtools) {
mainWindow.webContents.openDevTools()
}

mainWindow.on('focus', () => {
mainWindow.webContents.send('focus')
})

mainWindow.on('blur', () => {
mainWindow.webContents.send('blur')
})

/**
* If you install `show: true` then it can cause issues when trying to close the window.
Expand All @@ -58,9 +145,8 @@ const createWindow = async () => {
* @see https://github.com/electron/electron/issues/25012
*/
mainWindow.on('ready-to-show', async () => {
mainWindow?.show()
if (isDevelopment) {
mainWindow?.webContents.openDevTools()
if (rendererReady) {
mainWindow.show()
}
})

Expand All @@ -70,6 +156,7 @@ const createWindow = async () => {
app
.whenReady()
.then(enforceApplicationFolder)
.then(initMain)
.then(createWindow)
.catch((e) => {
console.error('Failed create window:', e)
Expand Down
Loading

0 comments on commit d0a814c

Please sign in to comment.