Skip to content

Commit 1fa585e

Browse files
authored
feat: add settings page (#622)
* feat: refactor settings dropdown * feat: create settings page * wip test * teste: add tests case * feat: removed settings dropdown * leftover * refactor wording * feat: create use-download-file hook * test: replace expect check * refactor version tab * fix test * refactor general tab
1 parent 7ddb17a commit 1fa585e

File tree

18 files changed

+1265
-184
lines changed

18 files changed

+1265
-184
lines changed

main/src/main.ts

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import {
1111
} from 'electron'
1212
import path from 'node:path'
1313
import { updateElectronApp } from 'update-electron-app'
14-
import { existsSync } from 'node:fs'
14+
import { existsSync, readFile } from 'node:fs'
1515
import started from 'electron-squirrel-startup'
1616
import * as Sentry from '@sentry/electron/main'
1717
import { initTray, updateTrayStatus } from './system-tray'
@@ -35,7 +35,6 @@ import {
3535
import log from './logger'
3636
import { getAppVersion, isOfficialReleaseBuild, pollWindowReady } from './util'
3737
import { delay } from '../../utils/delay'
38-
3938
import Store from 'electron-store'
4039

4140
const store = new Store<{
@@ -584,5 +583,31 @@ ipcMain.handle('sentry.opt-out', (): boolean => {
584583

585584
ipcMain.handle('sentry.opt-in', (): boolean => {
586585
store.set('isTelemetryEnabled', true)
587-
return store.get('isTelemetryEnabled', true)
586+
return true
588587
})
588+
589+
// Log file operations
590+
ipcMain.handle(
591+
'get-main-log-content',
592+
async (): Promise<string | undefined> => {
593+
try {
594+
const logPath = path.join(app.getPath('logs'), 'main.log')
595+
if (!existsSync(logPath)) {
596+
log.warn(`Log file does not exist: ${logPath}`)
597+
return
598+
}
599+
600+
const content = await new Promise<string>((resolve, reject) => {
601+
readFile(logPath, 'utf8', (err, data) => {
602+
if (err) reject(err)
603+
else resolve(data)
604+
})
605+
})
606+
607+
return content
608+
} catch (error) {
609+
log.error('Failed to read log file:', error)
610+
return
611+
}
612+
}
613+
)

preload/src/preload.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
import { contextBridge, ipcRenderer } from 'electron'
55
import type { WorkloadsWorkload } from '../../renderer/src/common/api/generated/types.gen'
6+
import { TOOLHIVE_VERSION } from '../../utils/constants'
67

78
// Expose auto-launch functionality to renderer
89
contextBridge.exposeInMainWorld('electronAPI', {
@@ -23,6 +24,7 @@ contextBridge.exposeInMainWorld('electronAPI', {
2324

2425
// ToolHive port
2526
getToolhivePort: () => ipcRenderer.invoke('get-toolhive-port'),
27+
getToolhiveVersion: () => TOOLHIVE_VERSION,
2628
// ToolHive is running
2729
isToolhiveRunning: () => ipcRenderer.invoke('is-toolhive-running'),
2830

@@ -72,6 +74,9 @@ contextBridge.exposeInMainWorld('electronAPI', {
7274
optOut: () => ipcRenderer.invoke('sentry.opt-out'),
7375
},
7476

77+
// Log file operations
78+
getMainLogContent: () => ipcRenderer.invoke('get-main-log-content'),
79+
7580
// Window controls
7681
windowControls: {
7782
minimize: () => ipcRenderer.invoke('window-minimize'),
@@ -108,6 +113,7 @@ export interface ElectronAPI {
108113
hideApp: () => Promise<void>
109114
quitApp: () => Promise<void>
110115
getToolhivePort: () => Promise<number | undefined>
116+
getToolhiveVersion: () => Promise<string>
111117
isToolhiveRunning: () => Promise<boolean>
112118
checkContainerEngine: () => Promise<{
113119
docker: boolean
@@ -133,6 +139,7 @@ export interface ElectronAPI {
133139
optIn: () => Promise<boolean>
134140
optOut: () => Promise<boolean>
135141
}
142+
getMainLogContent: () => Promise<string>
136143
isMac: boolean
137144
isWindows: boolean
138145
isLinux: boolean

renderer/src/common/components/layout/top-nav/index.tsx

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
11
import type { HTMLProps } from 'react'
2-
3-
import { ThemeToggle } from '../../theme/theme-toggle'
4-
import { SettingsDropdown } from '../../settings/settings-dropdown'
52
import { HelpDropdown } from '../../help'
63
import { WindowControls } from './window-controls'
74
import {
@@ -17,6 +14,7 @@ import { TopNavContainer } from './container'
1714
import { Separator } from '../../ui/separator'
1815
import { useConfirmQuit } from '@/common/hooks/use-confirm-quit'
1916
import { QuitConfirmationListener } from './quit-confirmation-listener'
17+
import { SettingsIcon } from 'lucide-react'
2018

2119
function TopNavLinks() {
2220
return (
@@ -165,8 +163,9 @@ export function TopNav(props: HTMLProps<HTMLElement>) {
165163
<TopNavLinks />
166164
<Separator orientation="vertical" />
167165
<div className="flex items-center gap-2">
168-
<ThemeToggle className="app-region-no-drag" />
169-
<SettingsDropdown className="app-region-no-drag" />
166+
<LinkViewTransition to="/settings" className="app-region-no-drag">
167+
<SettingsIcon className="text-muted-foreground size-4" />
168+
</LinkViewTransition>
170169
<HelpDropdown className="app-region-no-drag" />
171170
</div>
172171
</div>

renderer/src/common/components/settings/settings-dropdown.tsx

Lines changed: 0 additions & 111 deletions
This file was deleted.

0 commit comments

Comments
 (0)