Skip to content

Commit

Permalink
Typechecking for sendFrontendMessage
Browse files Browse the repository at this point in the history
  • Loading branch information
CommandMC committed Mar 24, 2024
1 parent 8a27b95 commit 52bc8e6
Show file tree
Hide file tree
Showing 13 changed files with 115 additions and 62 deletions.
9 changes: 7 additions & 2 deletions src/backend/api/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import {
Runner,
InstallPlatform,
WineCommandArgs,
ConnectivityChangedCallback,
ConnectivityStatus,
AppSettings,
GameSettings,
Expand Down Expand Up @@ -115,7 +114,13 @@ export const runWineCommandForGame = async (args: RunWineCommandArgs) =>
ipcRenderer.invoke('runWineCommandForGame', args)

export const onConnectivityChanged = async (
callback: ConnectivityChangedCallback
callback: (
event: Electron.IpcRendererEvent,
status: {
status: ConnectivityStatus
retryIn: number
}
) => void
) => ipcRenderer.on('connectivity-changed', callback)

export const getConnectivityStatus = async () =>
Expand Down
9 changes: 6 additions & 3 deletions src/backend/api/library.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { ipcRenderer } from 'electron'
import {
Runner,
InstallParams,
LaunchParams,
ImportGameArgs,
GameStatus,
Expand Down Expand Up @@ -74,11 +73,15 @@ export const handleLaunchGame = (
) => ipcRenderer.on('launchGame', callback)

export const handleInstallGame = (
callback: (event: Electron.IpcRendererEvent, args: InstallParams) => void
callback: (
event: Electron.IpcRendererEvent,
appName: string,
runner: Runner
) => void
) => ipcRenderer.on('installGame', callback)

export const handleRefreshLibrary = (
callback: (event: Electron.IpcRendererEvent, runner: Runner) => void
callback: (event: Electron.IpcRendererEvent, runner?: Runner) => void
) => ipcRenderer.on('refreshLibrary', callback)

export const handleGamePush = (
Expand Down
5 changes: 3 additions & 2 deletions src/backend/api/misc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -127,8 +127,9 @@ export const pathExists = async (path: string) =>
export const processShortcut = async (combination: string) =>
ipcRenderer.send('processShortcut', combination)

// eslint-disable-next-line @typescript-eslint/no-explicit-any
export const handleGoToScreen = (callback: any) => {
export const handleGoToScreen = (
callback: (e: Electron.IpcRendererEvent, screen: string) => void
) => {
ipcRenderer.on('openScreen', callback)
return () => {
ipcRenderer.removeListener('openScreen', callback)
Expand Down
2 changes: 1 addition & 1 deletion src/backend/api/wine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ export const refreshWineVersionInfo = async (fetch?: boolean): Promise<void> =>
export const handleProgressOfWinetricks = (
onProgress: (
e: Electron.IpcRendererEvent,
payload: { messages: string[]; installingComponent: '' }
payload: { messages: string[]; installingComponent: string }
) => void
): (() => void) => {
ipcRenderer.on('progressOfWinetricks', onProgress)
Expand Down
6 changes: 5 additions & 1 deletion src/backend/main_window.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { AppSettings, WindowProps } from 'common/types'
import { BrowserWindow, screen } from 'electron'
import path from 'path'
import { configStore } from './constants'
import type { FrontendMessages } from 'common/types/frontend_messages'

let mainWindow: BrowserWindow | null = null

Expand All @@ -18,7 +19,10 @@ export const isFrameless = () => {
// send a message to the main window's webContents if available
// returns `false` if no mainWindow or no webContents
// returns `true` if the message was sent to the webContents
export const sendFrontendMessage = (message: string, ...payload: unknown[]) => {
export const sendFrontendMessage = <MessageName extends keyof FrontendMessages>(
message: MessageName,
...payload: Parameters<FrontendMessages[MessageName]>
) => {
// get the first BrowserWindow if for some reason we don't have a webContents
if (!mainWindow?.webContents) {
mainWindow = BrowserWindow.getAllWindows()[0]
Expand Down
7 changes: 2 additions & 5 deletions src/backend/protocol.ts
Original file line number Diff line number Diff line change
Expand Up @@ -135,18 +135,15 @@ async function handleLaunch(
icon: icon
})
if (response === 0) {
return sendFrontendMessage('installGame', {
appName: app_name,
runner: gameRunner
})
return sendFrontendMessage('installGame', app_name, gameRunner)
}
if (response === 1) {
return logInfo('Not installing game', LogPrefix.ProtocolHandler)
}
}

mainWindow?.hide()
sendFrontendMessage('launchGame', arg, gameRunner)
sendFrontendMessage('launchGame', app_name, gameRunner)
}

/**
Expand Down
7 changes: 3 additions & 4 deletions src/backend/tools/ipc_handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,9 @@ ipcMain.handle('callTool', async (event, { tool, exe, appName, runner }) => {
if (runner === 'gog') {
// Check if game was modified by offline installer / wine uninstaller
await GOGLibraryManager.checkForOfflineInstallerChanges(appName)
sendFrontendMessage(
'pushGameToLibrary',
GOGLibraryManager.getGameInfo(appName)
)
const maybeNewGameInfo = GOGLibraryManager.getGameInfo(appName)
if (maybeNewGameInfo)
sendFrontendMessage('pushGameToLibrary', maybeNewGameInfo)
}

sendGameStatusUpdate({ appName, runner, status: 'done' })
Expand Down
2 changes: 1 addition & 1 deletion src/backend/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -870,7 +870,7 @@ export async function downloadDefaultWine() {

// download the latest version
const onProgress = (state: State, progress?: ProgressInfo) => {
sendFrontendMessage('progressOfWineManager' + release.version, {
sendFrontendMessage(`progressOfWineManager${release.version}`, {
state,
progress
})
Expand Down
2 changes: 1 addition & 1 deletion src/backend/wine/manager/ipc_handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { sendFrontendMessage } from '../../main_window'

ipcMain.handle('installWineVersion', async (e, release) => {
const onProgress = (state: State, progress?: ProgressInfo) => {
sendFrontendMessage('progressOfWineManager' + release.version, {
sendFrontendMessage(`progressOfWineManager${release.version}`, {
state,
progress
})
Expand Down
7 changes: 1 addition & 6 deletions src/common/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
GameMetadataInner,
LegendaryInstallInfo
} from './types/legendary'
import { IpcRendererEvent, TitleBarOverlay } from 'electron'
import { TitleBarOverlay } from 'electron'
import { ChildProcess } from 'child_process'
import type { HowLongToBeatEntry } from 'backend/wiki_game_info/howlongtobeat/utils'
import { NileInstallInfo, NileInstallPlatform } from './types/nile'
Expand Down Expand Up @@ -541,11 +541,6 @@ export type InstallPlatform =
| NileInstallPlatform
| 'Browser'

export type ConnectivityChangedCallback = (
event: IpcRendererEvent,
status: ConnectivityStatus
) => void

export type ConnectivityStatus = 'offline' | 'check-online' | 'online'

export interface Tools {
Expand Down
57 changes: 57 additions & 0 deletions src/common/types/frontend_messages.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import type {
ButtonOptions,
ConnectivityStatus,
DialogType,
DMQueueElement,
DownloadManagerState,
GameInfo,
GameStatus,
ProgressInfo,
RecentGame,
Runner,
State
} from 'common/types'

type FrontendMessages = {
gameStatusUpdate: (status: GameStatus) => void
wineVersionsUpdated: () => void
showDialog: (
title: string,
message: string,
type: DialogType,
buttons?: Array<ButtonOptions>
) => void
changedDMQueueInformation: (
elements: DMQueueElement[],
state: DownloadManagerState
) => void
maximized: () => void
unmaximized: () => void
fullscreen: (status: boolean) => void
refreshLibrary: (runner?: Runner) => void
openScreen: (screen: string) => void
'connectivity-changed': (status: {
status: ConnectivityStatus
retryIn: number
}) => void
launchGame: (appName: string, runner: Runner) => void
installGame: (appName: string, runner: Runner) => void
recentGamesChanged: (newRecentGames: RecentGame[]) => void
pushGameToLibrary: (info: GameInfo) => void
progressOfWinetricks: (payload: {
messages: string[]
installingComponent: string
}) => void
'installing-winetricks-component': (component: string) => void

[key: `progressUpdate${string}`]: (progress: GameStatus) => void
[key: `progressOfWineManager${string}`]: (progress: {
state: State
progress?: ProgressInfo
}) => void

// Used inside tests, so we can be a bit lenient with the type checking here
message: (...params: unknown[]) => void
}

export type { FrontendMessages }
2 changes: 1 addition & 1 deletion src/frontend/components/UI/Sidebar/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ export default React.memo(function Sidebar() {
}, [sidebarEl])

useEffect(() => {
window.api.handleGoToScreen((e: Event, screen: string) => {
window.api.handleGoToScreen((e, screen) => {
// handle navigate to screen
navigate(screen, { state: { fromGameCard: false } })
})
Expand Down
62 changes: 27 additions & 35 deletions src/frontend/state/GlobalState.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import {
RefreshOptions,
Runner,
WineVersionInfo,
InstallParams,
LibraryTopSectionOptions,
ExperimentalFeatures
} from 'common/types'
Expand Down Expand Up @@ -773,44 +772,37 @@ class GlobalState extends PureComponent<Props> {
}
)

window.api.handleInstallGame(
async (e: IpcRendererEvent, args: InstallParams) => {
const currentApp = libraryStatus.filter(
(game) => game.appName === appName
)[0]
const { appName, runner } = args
if (!currentApp || (currentApp && currentApp.status !== 'installing')) {
const gameInfo = await getGameInfo(appName, runner)
if (!gameInfo || gameInfo.runner === 'sideload') {
return
}
return this.setState({
showInstallModal: {
show: true,
appName,
runner,
gameInfo
}
})
window.api.handleInstallGame(async (e, appName, runner) => {
const currentApp = libraryStatus.filter(
(game) => game.appName === appName
)[0]
if (!currentApp || (currentApp && currentApp.status !== 'installing')) {
const gameInfo = await getGameInfo(appName, runner)
if (!gameInfo || gameInfo.runner === 'sideload') {
return
}
return this.setState({
showInstallModal: {
show: true,
appName,
runner,
gameInfo
}
})
}
)
})

window.api.handleGameStatus(
async (e: IpcRendererEvent, args: GameStatus) => {
return this.handleGameStatus({ ...args })
}
)
window.api.handleGameStatus((e, args) => {
this.handleGameStatus({ ...args })
})

window.api.handleRefreshLibrary(
async (e: IpcRendererEvent, runner: Runner) => {
this.refreshLibrary({
checkForUpdates: false,
runInBackground: true,
library: runner
})
}
)
window.api.handleRefreshLibrary((e, runner) => {
this.refreshLibrary({
checkForUpdates: false,
runInBackground: true,
library: runner
})
})

window.api.handleGamePush((e: IpcRendererEvent, args: GameInfo) => {
if (!args.app_name) return
Expand Down

0 comments on commit 52bc8e6

Please sign in to comment.