Skip to content

Commit

Permalink
feat: ability to set developer mode in desktop client
Browse files Browse the repository at this point in the history
  • Loading branch information
BluDood committed Oct 25, 2024
1 parent 82dd8d6 commit 640ccb9
Show file tree
Hide file tree
Showing 7 changed files with 107 additions and 19 deletions.
13 changes: 10 additions & 3 deletions src/main/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,15 @@ function createWindow(): void {
}

app.on('ready', async () => {
if (
process.env.NODE_ENV === 'development' &&
(await getStorageValue('devMode')) === null
) {
await setStorageValue('devMode', true)
}

log('Welcome!', 'GlanceThing')
if (isDev) log('Running in development mode', 'GlanceThing')
if (await isDev()) log('Running in development mode', 'GlanceThing')
electronApp.setAppUserModelId('com.bludood.glancething')

const adbPath = await getAdbExecutable().catch(err => ({ err }))
Expand Down Expand Up @@ -285,8 +292,8 @@ async function setupIpcHandlers() {
await updateApps()
})

ipcMain.handle(IPCHandler.IsDevMode, () => {
return isDev
ipcMain.handle(IPCHandler.IsDevMode, async () => {
return await isDev()
})

ipcMain.handle(IPCHandler.SetSpotifyToken, async (_event, token) => {
Expand Down
5 changes: 4 additions & 1 deletion src/main/lib/utils.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import { exec } from 'child_process'
import crypto from 'crypto'

export const isDev = process.env.NODE_ENV === 'development'
import { getStorageValue } from './storage.js'

export const isDev = async () =>
(await getStorageValue('devMode')) === true

export const random = (len: number) =>
crypto.randomBytes(len).toString('hex')
Expand Down
5 changes: 4 additions & 1 deletion src/main/lib/webapp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@ import fs from 'fs'
import { execAsync, isDev, log } from './utils.js'

export async function getWebAppDir() {
if (isDev && fs.existsSync(path.join(process.cwd(), 'client/dist'))) {
if (
(await isDev()) &&
fs.existsSync(path.join(process.cwd(), 'client/dist'))
) {
log('Using local client webapp', 'Client Webapp')
return path.join(process.cwd(), 'client/dist')
}
Expand Down
10 changes: 3 additions & 7 deletions src/renderer/src/components/Titlebar/Titlebar.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React, { useContext, useEffect, useState } from 'react'
import React, { useContext } from 'react'
import { useNavigate } from 'react-router-dom'

import { DevModeContext } from '@/contexts/DevModeContext.js'
import { ModalContext } from '@/contexts/ModalContext.js'

import styles from './Titlebar.module.css'
Expand All @@ -9,8 +10,7 @@ const Titlebar: React.FC = () => {
const navigate = useNavigate()
const { setSettingsOpen, setShortcutsEditorOpen } =
useContext(ModalContext)

const [devMode, setDevMode] = useState(false)
const { devMode } = useContext(DevModeContext)

const buttons = [
...(devMode
Expand All @@ -35,10 +35,6 @@ const Titlebar: React.FC = () => {
}
]

useEffect(() => {
window.api.isDevMode().then(setDevMode)
}, [])

return (
<div className={styles.titlebar}>
<div className={styles.actions}>
Expand Down
51 changes: 51 additions & 0 deletions src/renderer/src/contexts/DevModeContext.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { createContext, useEffect, useState } from 'react'

interface DevModeContextType {
devMode: boolean
checkDevMode: () => void
setDevMode: (devMode: boolean) => void
}

const DevModeContext = createContext<DevModeContextType>({
devMode: false,
checkDevMode: () => {},
setDevMode: () => {}
})

interface DevModeContextProviderProps {
children: React.ReactNode
}

const DevModeContextProvider = ({
children
}: DevModeContextProviderProps) => {
const [devMode, _setDevMode] = useState(false)

async function checkDevMode() {
const isDev = await window.api.isDevMode()
_setDevMode(isDev)
}

async function setDevMode(dev: boolean) {
await window.api.setStorageValue('devMode', dev)
await checkDevMode()
}

useEffect(() => {
checkDevMode()
}, [])

return (
<DevModeContext.Provider
value={{
devMode,
checkDevMode,
setDevMode
}}
>
{children}
</DevModeContext.Provider>
)
}

export { DevModeContext, DevModeContextProvider }
9 changes: 6 additions & 3 deletions src/renderer/src/main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React from 'react'
import ReactDOM from 'react-dom/client'
import { MemoryRouter } from 'react-router-dom'

import { DevModeContextProvider } from './contexts/DevModeContext.js'
import { ModalContextProvider } from './contexts/ModalContext.js'

import App from './App'
Expand All @@ -17,9 +18,11 @@ const root = ReactDOM.createRoot(
root.render(
<React.StrictMode>
<MemoryRouter>
<ModalContextProvider>
<App />
</ModalContextProvider>
<DevModeContextProvider>
<ModalContextProvider>
<App />
</ModalContextProvider>
</DevModeContextProvider>
</MemoryRouter>
</React.StrictMode>
)
33 changes: 29 additions & 4 deletions src/renderer/src/pages/Settings/Settings.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import React, { useContext, useEffect, useRef, useState } from 'react'

import { DevModeContext } from '@/contexts/DevModeContext.js'
import { ModalContext } from '@/contexts/ModalContext.js'

import Switch from '@/components/Switch/Switch.js'

import styles from './Settings.module.css'
Expand All @@ -17,8 +19,9 @@ enum Tab {

const Settings: React.FC = () => {
const { settingsOpen, setSettingsOpen } = useContext(ModalContext)
const { devMode } = useContext(DevModeContext)

const [currentTab, setCurrentTab] = useState<Tab>(Tab.General)
const [devMode, setDevMode] = useState(false)

function onClickBackground(e: React.MouseEvent<HTMLDivElement>) {
if (e.target === e.currentTarget) setSettingsOpen(false)
Expand All @@ -31,8 +34,8 @@ const Settings: React.FC = () => {
}, [settingsOpen, currentTab])

useEffect(() => {
window.api.isDevMode().then(setDevMode)
}, [])
if (!devMode && currentTab === Tab.Advanced) setCurrentTab(Tab.General)
})

return (
<div
Expand Down Expand Up @@ -317,6 +320,7 @@ const StartupTab: React.FC = () => {
}

const AdvancedTab: React.FC = () => {
const { setDevMode } = useContext(DevModeContext)
const [loaded, setLoaded] = useState(false)
const settings = useRef<{
disableSocketAuth?: boolean
Expand All @@ -337,6 +341,12 @@ const AdvancedTab: React.FC = () => {
return (
loaded && (
<div className={styles.settingsTab}>
<ToggleSetting
label="Developer Mode"
description="Enables some options for development purposes."
defaultValue={true}
onChange={() => setDevMode(false)}
/>
<ToggleSetting
label="Disable WebSocket Authentication"
description="Allows connections to the WebSocket server without authentication."
Expand All @@ -351,19 +361,34 @@ const AdvancedTab: React.FC = () => {
}

const AboutTab: React.FC = () => {
const { devMode, setDevMode } = useContext(DevModeContext)
const [version, setVersion] = useState<string | null>(null)
const [timesClicked, setTimesClicked] = useState(0)

useEffect(() => {
window.api.getVersion().then(setVersion)
}, [])

useEffect(() => {
if (timesClicked <= 0) return

if (devMode) return

if (timesClicked >= 5) setDevMode(true)
}, [timesClicked])

return (
<div className={styles.aboutTab}>
<div className={styles.app}>
<img src={icon} alt="" />
<div className={styles.info}>
<h2>GlanceThing</h2>
<p className={styles.version}>Version {version}</p>
<p
onClick={() => setTimesClicked(t => (t += 1))}
className={styles.version}
>
Version {version}
</p>
</div>
</div>
<h2>Credits</h2>
Expand Down

0 comments on commit 640ccb9

Please sign in to comment.