Skip to content

Commit

Permalink
ℹ️ #8 Add about window
Browse files Browse the repository at this point in the history
  • Loading branch information
c-o-l-i-n committed Aug 18, 2022
1 parent 933f2b6 commit cb0e0bd
Show file tree
Hide file tree
Showing 24 changed files with 185 additions and 108 deletions.
5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,10 @@
{
"html": "./src/renderer/common/index.html",
"js": "./src/renderer/about-window/index.tsx",
"name": "about_window"
"name": "about_window",
"preload": {
"js": "./src/main/preload.ts"
}
}
]
}
Expand Down
2 changes: 1 addition & 1 deletion src/main/generate-instrument-parts-and-master.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { PDFDocument } from 'pdf-lib'
import path from 'path'
import fs from 'fs'
import validFilename from 'valid-filename'
import { GeneratePayload } from '../types'
import { GeneratePayload } from '../types/types'

const generateInstrumentPartsAndMaster = async (payload: GeneratePayload) => {
// unwrap payload
Expand Down
19 changes: 17 additions & 2 deletions src/main/ipc-main.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import Store from 'electron-store'
import { app, BrowserWindow, dialog, ipcMain } from 'electron'
import { app, BrowserWindow, dialog, ipcMain, shell } from 'electron'
import separateSongParts from './separate-song-parts'
import generateInstrumentPartsAndMaster from './generate-instrument-parts-and-master'
import {
AppInfo,
ExternalSite,
GeneratePayload,
IpcMainMessage,
MessageBoxType,
SepatatePayload,
} from '../types'
} from '../types/types'

const setupIpcMain = (mainWindow: BrowserWindow) => {
const showMessageBox = (type: MessageBoxType, message: string) => {
Expand Down Expand Up @@ -80,6 +82,19 @@ const setupIpcMain = (mainWindow: BrowserWindow) => {
}
}
)

ipcMain.handle(
IpcMainMessage.GET_APP_INFO,
(): AppInfo => ({
name: app.name,
version: app.getVersion(),
})
)

ipcMain.on(IpcMainMessage.OPEN_EXTERNAL, (e, site: ExternalSite) => {
if (!Object.values(ExternalSite).includes(site)) return
shell.openExternal(site)
})
}

export default setupIpcMain
96 changes: 39 additions & 57 deletions src/main/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,48 +4,33 @@ import unhandled from 'electron-unhandled'
import os from 'os'
import createAppMenu from './menu'
import setupIpcMain from './ipc-main'
import { ErrorReport, ExternalSite } from '../types/types'

declare const MAIN_WINDOW_WEBPACK_ENTRY: string
declare const ABOUT_WINDOW_WEBPACK_ENTRY: string
declare const MAIN_WINDOW_PRELOAD_WEBPACK_ENTRY: string
declare const ABOUT_WINDOW_PRELOAD_WEBPACK_ENTRY: string

if (require('electron-squirrel-startup')) process.exit()

const sendErrorReport = (
os: NodeJS.Platform,
osVersion: string,
appVersion: string,
electronVersion: string,
nodeVersion: string,
chromeVersion: string,
stackTrace: string
) => {
const params = new URLSearchParams({
os: os,
osv: osVersion,
av: appVersion,
ev: electronVersion,
nv: nodeVersion,
cv: chromeVersion,
stack: stackTrace,
})

shell.openExternal('https://prestoparts.org/report?' + params.toString())
const sendErrorReport = (errorReport: ErrorReport) => {
const params = new URLSearchParams({ ...errorReport })
shell.openExternal(`${ExternalSite.APP_WEBSITE}/report?${params.toString()}`)
}

// handles unhandled errors
unhandled({
showDialog: true,
reportButton: (error) => {
sendErrorReport(
process.platform,
os.release(),
app.getVersion(),
process.versions.electron,
process.versions.node,
process.versions.chrome,
error.stack
)
sendErrorReport({
os: process.platform,
osVersion: os.release(),
appVersion: app.getVersion(),
electronVersion: process.versions.electron,
nodeVersion: process.versions.node,
chromeVersion: process.versions.chrome,
stackTrace: error.stack,
})
},
})

Expand Down Expand Up @@ -87,48 +72,45 @@ const createWindow = () => {

mainWindow.once('ready-to-show', () => {
setupIpcMain(mainWindow)
createAboutWindow()
createAppMenu(isMac, app, aboutWindow)
mainWindow.show()
})

mainWindow.on('close', () => {
app.quit()
})

aboutWindow = new BrowserWindow({
show: false,
width: 270,
height: 278,
resizable: false,
minimizable: false,
maximizable: false,
webPreferences: {
nodeIntegration: true,
contextIsolation: false,
},
})
const createAboutWindow = () => {
aboutWindow = new BrowserWindow({
show: false,
width: 270,
height: 278,
resizable: false,
minimizable: false,
maximizable: false,
webPreferences: {
preload: ABOUT_WINDOW_PRELOAD_WEBPACK_ENTRY,
},
})

aboutWindow.setMenu(null)
aboutWindow.setMenu(null)

aboutWindow.loadURL(ABOUT_WINDOW_WEBPACK_ENTRY).then(() => {
aboutWindow.webContents.send('app-info', {
name: app.name,
version: app.getVersion(),
})
})
aboutWindow.loadURL(ABOUT_WINDOW_WEBPACK_ENTRY)

// hide window rather than destroy it on close
aboutWindow.on('close', (e) => {
// if this isn't here, the app won't ever quit
if (!appIsQuitting) {
e.preventDefault()
aboutWindow.hide()
}
})
// hide window rather than destroy it on close
aboutWindow.on('close', (e) => {
// if this isn't here, the app won't ever quit
if (!appIsQuitting) {
e.preventDefault()
aboutWindow.hide()
}
})
}
}

app.whenReady().then(() => {
createWindow()
createAppMenu(isMac, app, aboutWindow)
})

app.on('before-quit', () => {
Expand Down
5 changes: 2 additions & 3 deletions src/main/menu.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { App, BrowserWindow, Menu, shell } from 'electron'
import { ExternalSite } from '../types/types'

const createAppMenu = (
isMac: boolean,
Expand Down Expand Up @@ -45,9 +46,7 @@ const createAppMenu = (
const helpSubmenu: Electron.MenuItemConstructorOptions[] = [
{
label: 'Learn More',
click: async () => {
await shell.openExternal('https://prestoparts.org')
},
click: () => shell.openExternal(ExternalSite.APP_WEBSITE),
},
]

Expand Down
30 changes: 25 additions & 5 deletions src/main/preload.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,30 @@
import { contextBridge, ipcRenderer } from 'electron'
import { IpcMainMessage, IpcRendererApi, Maybe, Payload } from '../types'
import {
AppInfo,
ElectronApi,
ExternalSite,
IpcMainMessage,
Maybe,
Payload,
} from '../types/types'

const ipcRendererApi: IpcRendererApi = {
invoke(channel: IpcMainMessage, payload?: Payload): Promise<Maybe<string[]>> {
return ipcRenderer.invoke(channel, payload)
const electronApi: ElectronApi = {
async invoke(
channel: IpcMainMessage,
payload?: Payload
): Promise<Maybe<string>> {
const value: Maybe<string[]> = await ipcRenderer.invoke(channel, payload)
if (!value) {
return undefined
}
return value[0]
},
getAppInfo(): Promise<AppInfo> {
return ipcRenderer.invoke(IpcMainMessage.GET_APP_INFO)
},
openExternal(url: ExternalSite) {
ipcRenderer.send(IpcMainMessage.OPEN_EXTERNAL, url)
},
}

contextBridge.exposeInMainWorld('electron', { ipcRenderer: ipcRendererApi })
contextBridge.exposeInMainWorld('electron', electronApi)
2 changes: 1 addition & 1 deletion src/main/separate-song-parts.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { SepatatePayload } from '../types'
import { SepatatePayload } from '../types/types'
import { PDFDocument, degrees } from 'pdf-lib'
import path from 'path'
import fs from 'fs'
Expand Down
28 changes: 27 additions & 1 deletion src/renderer/about-window/AboutWindow.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,31 @@
import React from 'react'
import { AppInfo, ExternalSite } from '../../types/types'
import Logo from '../../../assets/app-icons/app-icon.iconset/icon_128x128.png'
import ExternalLink from './components/ExternalLink'

const AboutWindow = () => <div>About Window</div>
interface Props {
appInfo: AppInfo
}

const AboutWindow = ({ appInfo }: Props) => {
document.title = `About ${appInfo.name}`

return (
<main className='hero is-fullheight has-text-centered is-flex is-flex-direction-column is-justify-content-center is-align-items-center pb-2'>
<img src={Logo} alt='Presto Parts Icon' className='image is-64x64' />
<p className='is-size-5 has-text-weight-bold'>{appInfo.name}</p>
<p className='is-size-7'>{appInfo.version}</p>
<p className='mt-3'>Orangize your sheet music by part</p>
<p className='mt-2'>
<ExternalLink url={ExternalSite.APP_WEBSITE}>Website</ExternalLink>
</p>
<p className='is-size-7 mt-3'>
Navbar icons by{' '}
<ExternalLink url={ExternalSite.ICONS_8}>icons8</ExternalLink>
</p>
<p className='is-size-7 mt-2'>Copyright &copy; 2022 Colin A. Williams</p>
</main>
)
}

export default AboutWindow
13 changes: 13 additions & 0 deletions src/renderer/about-window/components/ExternalLink.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import React from 'react'
import { ExternalSite } from '../../../types/types'

interface Props {
children: React.ReactNode
url: ExternalSite
}

const ExternalLink = ({ children, url }: Props) => {
return <a onClick={() => window.electron.openExternal(url)}>{children}</a>
}

export default ExternalLink
13 changes: 8 additions & 5 deletions src/renderer/about-window/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,11 @@ const el = document.getElementById('root')
if (el === null) throw new Error('Root container missing in index.html')

const root = ReactDOM.createRoot(el)
root.render(
<React.StrictMode>
<AboutWindow />
</React.StrictMode>
)

window.electron.getAppInfo().then((appInfo) => {
root.render(
<React.StrictMode>
<AboutWindow appInfo={appInfo} />
</React.StrictMode>
)
})
3 changes: 1 addition & 2 deletions src/renderer/main-window/MainWindow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@ import React, { useContext } from 'react'
import Navbar from './components/Navbar'
import CutIcon from '../../../assets/images/cut.svg'
import SheetMusicIcon from '../../../assets/images/sheet-music.svg'
import { Page, Tab } from '../../types'
import { ActivePageProvider } from './context/ActivePageContext'
import { Page, Tab } from '../../types/types'
import SeparatePage from './pages/SeparatePage'
import GeneratePage from './pages/GeneratePage'
import Loader from './components/Loader'
Expand Down
4 changes: 2 additions & 2 deletions src/renderer/main-window/components/GoButton.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React, { useContext } from 'react'
import { IpcMainMessage, Payload } from '../../../types'
import { IpcMainMessage, Payload } from '../../../types/types'
import IsLoadingContext from '../context/IsLoadingContext'

interface Props {
Expand All @@ -12,7 +12,7 @@ const GoButton = ({ ipcMessage, payload }: Props) => {

const go = async () => {
setIsLoading(true)
await window.electron.ipcRenderer.invoke(ipcMessage, payload)
await window.electron.invoke(ipcMessage, payload)
setIsLoading(false)
}

Expand Down
2 changes: 1 addition & 1 deletion src/renderer/main-window/components/Navbar.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from 'react'
import { Tab } from '../../../types'
import { Tab } from '../../../types/types'
import NavbarTab from './NavbarTab'

interface Props {
Expand Down
2 changes: 1 addition & 1 deletion src/renderer/main-window/components/NavbarTab.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React, { useContext } from 'react'
import { Tab } from '../../../types'
import { Tab } from '../../../types/types'
import ActivePageContext from '../context/ActivePageContext'

interface Props {
Expand Down
2 changes: 1 addition & 1 deletion src/renderer/main-window/context/ActivePageContext.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React, { createContext, useState } from 'react'
import { Page, Context } from '../../../types'
import { Page, Context } from '../../../types/types'

const initialActivePage = Page.SEPARATE

Expand Down
2 changes: 1 addition & 1 deletion src/renderer/main-window/context/IsLoadingContext.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React, { createContext, useState } from 'react'
import { Context } from '../../../types'
import { Context } from '../../../types/types'

const initialIsLoading = false

Expand Down
6 changes: 3 additions & 3 deletions src/renderer/main-window/pages/GeneratePage.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React, { useContext, useState } from 'react'
import { IpcMainMessage, Page } from '../../../types'
import { IpcMainMessage, Page } from '../../../types/types'
import FileUploadField from '../components/FileUploadField'
import GoButton from '../components/GoButton'
import TextAreaField from '../components/TextAreaField'
Expand All @@ -17,12 +17,12 @@ const GeneratePage = () => {
if (activePage !== Page.GENERATE) return

const chooseSongFoldersLocation = async () => {
const folderPath = await window.electron.ipcRenderer.invoke(
const folderPath = await window.electron.invoke(
IpcMainMessage.CHOOSE_SONG_FOLDERS_LOCATION
)

if (folderPath) {
setSongFoldersLocation(folderPath[0])
setSongFoldersLocation(folderPath)
}
}

Expand Down
Loading

0 comments on commit cb0e0bd

Please sign in to comment.