@kitlangton/ghui 0.1.12 → 0.1.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/App.tsx +23 -22
- package/src/ui/FooterHints.tsx +1 -1
- package/src/ui/colors.ts +216 -1
- package/src/ui/modals.tsx +2 -3
package/package.json
CHANGED
package/src/App.tsx
CHANGED
|
@@ -198,7 +198,7 @@ const copyPullRequestMetadata = async (pullRequest: PullRequestItem) => {
|
|
|
198
198
|
|
|
199
199
|
const isShiftG = (key: { readonly name: string; readonly shift?: boolean }) => key.name === "G" || key.name === "g" && key.shift
|
|
200
200
|
|
|
201
|
-
const
|
|
201
|
+
const isThemeKey = (key: { readonly name: string; readonly ctrl?: boolean; readonly meta?: boolean }) => !key.ctrl && !key.meta && key.name.toLowerCase() === "t"
|
|
202
202
|
|
|
203
203
|
const getDetailPlaceholderContent = ({
|
|
204
204
|
status,
|
|
@@ -278,8 +278,10 @@ export const App = () => {
|
|
|
278
278
|
const getPullRequestDiff = useAtomSet(getPullRequestDiffAtom, { mode: "promise" })
|
|
279
279
|
const getPullRequestMergeInfo = useAtomSet(getPullRequestMergeInfoAtom, { mode: "promise" })
|
|
280
280
|
const mergePullRequest = useAtomSet(mergePullRequestAtom, { mode: "promise" })
|
|
281
|
-
const
|
|
282
|
-
const
|
|
281
|
+
const terminalWidth = width ?? 100
|
|
282
|
+
const terminalHeight = height ?? 24
|
|
283
|
+
const contentWidth = Math.max(1, terminalWidth)
|
|
284
|
+
const isWideLayout = terminalWidth >= 100
|
|
283
285
|
const splitGap = 1
|
|
284
286
|
const sectionPadding = 1
|
|
285
287
|
const leftPaneWidth = isWideLayout ? Math.max(44, Math.floor((contentWidth - splitGap) * 0.56)) : contentWidth
|
|
@@ -287,8 +289,8 @@ export const App = () => {
|
|
|
287
289
|
const dividerJunctionAt = Math.max(1, leftPaneWidth)
|
|
288
290
|
const leftContentWidth = isWideLayout ? Math.max(24, leftPaneWidth - 3) : Math.max(24, contentWidth - sectionPadding * 2)
|
|
289
291
|
const rightContentWidth = isWideLayout ? Math.max(24, rightPaneWidth - sectionPadding * 2) : Math.max(24, contentWidth - sectionPadding * 2)
|
|
290
|
-
const wideDetailLines = Math.max(8,
|
|
291
|
-
const wideBodyHeight = Math.max(8,
|
|
292
|
+
const wideDetailLines = Math.max(8, terminalHeight - 8) // fill available vertical space
|
|
293
|
+
const wideBodyHeight = Math.max(8, terminalHeight - 4)
|
|
292
294
|
const noticeTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null)
|
|
293
295
|
const pendingGTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null)
|
|
294
296
|
const diffPrefetchTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null)
|
|
@@ -557,13 +559,12 @@ export const App = () => {
|
|
|
557
559
|
setMergeModal(initialMergeModalState)
|
|
558
560
|
setThemeModal({
|
|
559
561
|
open: true,
|
|
560
|
-
selectedIndex: Math.max(0, themeDefinitions.findIndex((theme) => theme.id === themeId)),
|
|
561
562
|
initialThemeId: themeId,
|
|
562
563
|
})
|
|
563
564
|
}
|
|
564
565
|
|
|
565
566
|
const closeThemeModal = (confirm: boolean) => {
|
|
566
|
-
const selectedTheme = themeDefinitions
|
|
567
|
+
const selectedTheme = themeDefinitions.find((theme) => theme.id === themeId)
|
|
567
568
|
if (!confirm) {
|
|
568
569
|
setThemeId(themeModal.initialThemeId)
|
|
569
570
|
} else if (selectedTheme) {
|
|
@@ -573,11 +574,11 @@ export const App = () => {
|
|
|
573
574
|
}
|
|
574
575
|
|
|
575
576
|
const moveThemeSelection = (delta: number) => {
|
|
576
|
-
const
|
|
577
|
-
|
|
577
|
+
const currentIndex = Math.max(0, themeDefinitions.findIndex((theme) => theme.id === themeId))
|
|
578
|
+
const selectedIndex = Math.max(0, Math.min(themeDefinitions.length - 1, currentIndex + delta))
|
|
579
|
+
if (selectedIndex === currentIndex) return
|
|
578
580
|
const theme = themeDefinitions[selectedIndex]
|
|
579
581
|
if (theme && theme.id !== themeId) setThemeId(theme.id)
|
|
580
|
-
setThemeModal((current) => ({ ...current, selectedIndex }))
|
|
581
582
|
}
|
|
582
583
|
|
|
583
584
|
const openLabelModal = () => {
|
|
@@ -1032,7 +1033,7 @@ export const App = () => {
|
|
|
1032
1033
|
}
|
|
1033
1034
|
}
|
|
1034
1035
|
|
|
1035
|
-
if (
|
|
1036
|
+
if (isThemeKey(key)) {
|
|
1036
1037
|
openThemeModal()
|
|
1037
1038
|
return
|
|
1038
1039
|
}
|
|
@@ -1183,7 +1184,7 @@ export const App = () => {
|
|
|
1183
1184
|
})
|
|
1184
1185
|
|
|
1185
1186
|
const fullscreenContentWidth = Math.max(24, contentWidth - 2)
|
|
1186
|
-
const fullscreenBodyLines = Math.max(8,
|
|
1187
|
+
const fullscreenBodyLines = Math.max(8, terminalHeight - 8)
|
|
1187
1188
|
const wideFullscreenDetailScrollable = getDetailsPaneHeight({
|
|
1188
1189
|
pullRequest: selectedPullRequest,
|
|
1189
1190
|
contentWidth: fullscreenContentWidth,
|
|
@@ -1214,20 +1215,20 @@ export const App = () => {
|
|
|
1214
1215
|
|
|
1215
1216
|
const longestLabelName = labelModal.availableLabels.reduce((max, label) => Math.max(max, label.name.length), 0)
|
|
1216
1217
|
const labelModalWidth = Math.min(Math.max(42, longestLabelName + 16), 56, contentWidth - 4)
|
|
1217
|
-
const labelModalHeight = Math.min(20,
|
|
1218
|
+
const labelModalHeight = Math.min(20, terminalHeight - 4)
|
|
1218
1219
|
const labelModalLeft = Math.floor((contentWidth - labelModalWidth) / 2)
|
|
1219
|
-
const labelModalTop = Math.floor((
|
|
1220
|
+
const labelModalTop = Math.floor((terminalHeight - labelModalHeight) / 2)
|
|
1220
1221
|
const mergeModalWidth = Math.min(68, Math.max(46, contentWidth - 12))
|
|
1221
|
-
const mergeModalHeight = Math.min(16,
|
|
1222
|
+
const mergeModalHeight = Math.min(16, terminalHeight - 4)
|
|
1222
1223
|
const mergeModalLeft = Math.floor((contentWidth - mergeModalWidth) / 2)
|
|
1223
|
-
const mergeModalTop = Math.floor((
|
|
1224
|
+
const mergeModalTop = Math.floor((terminalHeight - mergeModalHeight) / 2)
|
|
1224
1225
|
const themeModalWidth = Math.min(58, Math.max(38, contentWidth - 12))
|
|
1225
|
-
const themeModalHeight = Math.min(
|
|
1226
|
+
const themeModalHeight = Math.min(16, terminalHeight - 4)
|
|
1226
1227
|
const themeModalLeft = Math.floor((contentWidth - themeModalWidth) / 2)
|
|
1227
|
-
const themeModalTop = Math.floor((
|
|
1228
|
+
const themeModalTop = Math.floor((terminalHeight - themeModalHeight) / 2)
|
|
1228
1229
|
|
|
1229
1230
|
return (
|
|
1230
|
-
<box
|
|
1231
|
+
<box width={terminalWidth} height={terminalHeight} flexDirection="column" backgroundColor={colors.background}>
|
|
1231
1232
|
<box paddingLeft={1} paddingRight={1} flexDirection="column" backgroundColor={colors.panel}>
|
|
1232
1233
|
<PlainLine text={headerLine} fg={colors.muted} bold />
|
|
1233
1234
|
</box>
|
|
@@ -1300,7 +1301,7 @@ export const App = () => {
|
|
|
1300
1301
|
</scrollbox>
|
|
1301
1302
|
</box>
|
|
1302
1303
|
) : (
|
|
1303
|
-
|
|
1304
|
+
<box height={wideBodyHeight} flexDirection="column">
|
|
1304
1305
|
<DetailsPane pullRequest={selectedPullRequest} contentWidth={rightContentWidth} paneWidth={contentWidth} placeholderContent={detailPlaceholderContent} loadingIndicator={loadingIndicator} />
|
|
1305
1306
|
<Divider width={contentWidth} />
|
|
1306
1307
|
<box flexGrow={1} flexDirection="column">
|
|
@@ -1310,7 +1311,7 @@ export const App = () => {
|
|
|
1310
1311
|
</box>
|
|
1311
1312
|
</scrollbox>
|
|
1312
1313
|
</box>
|
|
1313
|
-
|
|
1314
|
+
</box>
|
|
1314
1315
|
)}
|
|
1315
1316
|
|
|
1316
1317
|
{isWideLayout && !detailFullView && !diffFullView && !isInitialLoading ? (
|
|
@@ -1318,7 +1319,7 @@ export const App = () => {
|
|
|
1318
1319
|
) : (
|
|
1319
1320
|
<Divider width={contentWidth} />
|
|
1320
1321
|
)}
|
|
1321
|
-
<box paddingLeft={1} paddingRight={1} backgroundColor={colors.
|
|
1322
|
+
<box paddingLeft={1} paddingRight={1} backgroundColor={colors.footer}>
|
|
1322
1323
|
{footerNotice ? (
|
|
1323
1324
|
<PlainLine text={footerNotice} fg={colors.count} />
|
|
1324
1325
|
) : (
|
package/src/ui/FooterHints.tsx
CHANGED
|
@@ -86,7 +86,7 @@ export const FooterHints = ({
|
|
|
86
86
|
<TextLine>
|
|
87
87
|
<span fg={colors.count}>/</span>
|
|
88
88
|
<span fg={colors.muted}> filter </span>
|
|
89
|
-
<span fg={colors.count}>
|
|
89
|
+
<span fg={colors.count}>t</span>
|
|
90
90
|
<span fg={colors.muted}> theme </span>
|
|
91
91
|
{showFilterClear ? (
|
|
92
92
|
<>
|
package/src/ui/colors.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
export type ThemeId = "ghui" | "tokyo-night" | "opencode"
|
|
1
|
+
export type ThemeId = "ghui" | "tokyo-night" | "catppuccin" | "rose-pine" | "gruvbox" | "nord" | "dracula" | "opencode"
|
|
2
2
|
|
|
3
3
|
export interface ColorPalette {
|
|
4
4
|
readonly background: string
|
|
5
5
|
readonly panel: string
|
|
6
|
+
readonly footer: string
|
|
6
7
|
readonly modalBackground: string
|
|
7
8
|
readonly text: string
|
|
8
9
|
readonly muted: string
|
|
@@ -50,6 +51,7 @@ export interface ThemeDefinition {
|
|
|
50
51
|
const ghuiColors: ColorPalette = {
|
|
51
52
|
background: "#111018",
|
|
52
53
|
panel: "#161923",
|
|
54
|
+
footer: "#1d2430",
|
|
53
55
|
modalBackground: "#1a1a2e",
|
|
54
56
|
text: "#ede7da",
|
|
55
57
|
muted: "#9f9788",
|
|
@@ -90,6 +92,7 @@ const ghuiColors: ColorPalette = {
|
|
|
90
92
|
const tokyoNightColors: ColorPalette = {
|
|
91
93
|
background: "#1a1b26",
|
|
92
94
|
panel: "#16161e",
|
|
95
|
+
footer: "#24283b",
|
|
93
96
|
modalBackground: "#24283b",
|
|
94
97
|
text: "#c0caf5",
|
|
95
98
|
muted: "#787c99",
|
|
@@ -130,6 +133,7 @@ const tokyoNightColors: ColorPalette = {
|
|
|
130
133
|
const opencodeColors: ColorPalette = {
|
|
131
134
|
background: "#0a0a0a",
|
|
132
135
|
panel: "#141414",
|
|
136
|
+
footer: "#1e1e1e",
|
|
133
137
|
modalBackground: "#1e1e1e",
|
|
134
138
|
text: "#eeeeee",
|
|
135
139
|
muted: "#808080",
|
|
@@ -167,9 +171,219 @@ const opencodeColors: ColorPalette = {
|
|
|
167
171
|
},
|
|
168
172
|
}
|
|
169
173
|
|
|
174
|
+
const catppuccinColors: ColorPalette = {
|
|
175
|
+
background: "#1e1e2e",
|
|
176
|
+
panel: "#181825",
|
|
177
|
+
footer: "#313244",
|
|
178
|
+
modalBackground: "#313244",
|
|
179
|
+
text: "#cdd6f4",
|
|
180
|
+
muted: "#7f849c",
|
|
181
|
+
separator: "#45475a",
|
|
182
|
+
accent: "#cba6f7",
|
|
183
|
+
inlineCode: "#f5c2e7",
|
|
184
|
+
error: "#f38ba8",
|
|
185
|
+
selectedBg: "#45475a",
|
|
186
|
+
selectedText: "#f5e0dc",
|
|
187
|
+
count: "#fab387",
|
|
188
|
+
status: {
|
|
189
|
+
draft: "#f9e2af",
|
|
190
|
+
approved: "#a6e3a1",
|
|
191
|
+
changes: "#f38ba8",
|
|
192
|
+
review: "#89b4fa",
|
|
193
|
+
none: "#7f849c",
|
|
194
|
+
passing: "#a6e3a1",
|
|
195
|
+
pending: "#f9e2af",
|
|
196
|
+
failing: "#f38ba8",
|
|
197
|
+
},
|
|
198
|
+
repos: {
|
|
199
|
+
opencode: "#89b4fa",
|
|
200
|
+
"effect-smol": "#a6e3a1",
|
|
201
|
+
"opencode-console": "#f5c2e7",
|
|
202
|
+
opencontrol: "#fab387",
|
|
203
|
+
default: "#74c7ec",
|
|
204
|
+
},
|
|
205
|
+
diff: {
|
|
206
|
+
addedBg: "#243927",
|
|
207
|
+
removedBg: "#3b2532",
|
|
208
|
+
contextBg: "transparent",
|
|
209
|
+
lineNumberBg: "#181825",
|
|
210
|
+
addedLineNumberBg: "#203524",
|
|
211
|
+
removedLineNumberBg: "#36232f",
|
|
212
|
+
},
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
const rosePineColors: ColorPalette = {
|
|
216
|
+
background: "#191724",
|
|
217
|
+
panel: "#1f1d2e",
|
|
218
|
+
footer: "#26233a",
|
|
219
|
+
modalBackground: "#26233a",
|
|
220
|
+
text: "#e0def4",
|
|
221
|
+
muted: "#908caa",
|
|
222
|
+
separator: "#524f67",
|
|
223
|
+
accent: "#c4a7e7",
|
|
224
|
+
inlineCode: "#f6c177",
|
|
225
|
+
error: "#eb6f92",
|
|
226
|
+
selectedBg: "#403d52",
|
|
227
|
+
selectedText: "#f6f1ff",
|
|
228
|
+
count: "#ebbcba",
|
|
229
|
+
status: {
|
|
230
|
+
draft: "#f6c177",
|
|
231
|
+
approved: "#9ccfd8",
|
|
232
|
+
changes: "#eb6f92",
|
|
233
|
+
review: "#31748f",
|
|
234
|
+
none: "#908caa",
|
|
235
|
+
passing: "#9ccfd8",
|
|
236
|
+
pending: "#f6c177",
|
|
237
|
+
failing: "#eb6f92",
|
|
238
|
+
},
|
|
239
|
+
repos: {
|
|
240
|
+
opencode: "#31748f",
|
|
241
|
+
"effect-smol": "#9ccfd8",
|
|
242
|
+
"opencode-console": "#c4a7e7",
|
|
243
|
+
opencontrol: "#f6c177",
|
|
244
|
+
default: "#ebbcba",
|
|
245
|
+
},
|
|
246
|
+
diff: {
|
|
247
|
+
addedBg: "#23343a",
|
|
248
|
+
removedBg: "#3a2534",
|
|
249
|
+
contextBg: "transparent",
|
|
250
|
+
lineNumberBg: "#1f1d2e",
|
|
251
|
+
addedLineNumberBg: "#203137",
|
|
252
|
+
removedLineNumberBg: "#352330",
|
|
253
|
+
},
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
const gruvboxColors: ColorPalette = {
|
|
257
|
+
background: "#282828",
|
|
258
|
+
panel: "#1d2021",
|
|
259
|
+
footer: "#3c3836",
|
|
260
|
+
modalBackground: "#3c3836",
|
|
261
|
+
text: "#ebdbb2",
|
|
262
|
+
muted: "#928374",
|
|
263
|
+
separator: "#665c54",
|
|
264
|
+
accent: "#fabd2f",
|
|
265
|
+
inlineCode: "#d3869b",
|
|
266
|
+
error: "#fb4934",
|
|
267
|
+
selectedBg: "#504945",
|
|
268
|
+
selectedText: "#fbf1c7",
|
|
269
|
+
count: "#fe8019",
|
|
270
|
+
status: {
|
|
271
|
+
draft: "#fabd2f",
|
|
272
|
+
approved: "#b8bb26",
|
|
273
|
+
changes: "#fb4934",
|
|
274
|
+
review: "#83a598",
|
|
275
|
+
none: "#928374",
|
|
276
|
+
passing: "#b8bb26",
|
|
277
|
+
pending: "#fabd2f",
|
|
278
|
+
failing: "#fb4934",
|
|
279
|
+
},
|
|
280
|
+
repos: {
|
|
281
|
+
opencode: "#83a598",
|
|
282
|
+
"effect-smol": "#b8bb26",
|
|
283
|
+
"opencode-console": "#d3869b",
|
|
284
|
+
opencontrol: "#fe8019",
|
|
285
|
+
default: "#8ec07c",
|
|
286
|
+
},
|
|
287
|
+
diff: {
|
|
288
|
+
addedBg: "#32361f",
|
|
289
|
+
removedBg: "#3c2927",
|
|
290
|
+
contextBg: "transparent",
|
|
291
|
+
lineNumberBg: "#1d2021",
|
|
292
|
+
addedLineNumberBg: "#2f331e",
|
|
293
|
+
removedLineNumberBg: "#382726",
|
|
294
|
+
},
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
const nordColors: ColorPalette = {
|
|
298
|
+
background: "#2e3440",
|
|
299
|
+
panel: "#242933",
|
|
300
|
+
footer: "#3b4252",
|
|
301
|
+
modalBackground: "#3b4252",
|
|
302
|
+
text: "#eceff4",
|
|
303
|
+
muted: "#8892a7",
|
|
304
|
+
separator: "#4c566a",
|
|
305
|
+
accent: "#88c0d0",
|
|
306
|
+
inlineCode: "#b48ead",
|
|
307
|
+
error: "#bf616a",
|
|
308
|
+
selectedBg: "#434c5e",
|
|
309
|
+
selectedText: "#eceff4",
|
|
310
|
+
count: "#ebcb8b",
|
|
311
|
+
status: {
|
|
312
|
+
draft: "#ebcb8b",
|
|
313
|
+
approved: "#a3be8c",
|
|
314
|
+
changes: "#bf616a",
|
|
315
|
+
review: "#81a1c1",
|
|
316
|
+
none: "#8892a7",
|
|
317
|
+
passing: "#a3be8c",
|
|
318
|
+
pending: "#ebcb8b",
|
|
319
|
+
failing: "#bf616a",
|
|
320
|
+
},
|
|
321
|
+
repos: {
|
|
322
|
+
opencode: "#81a1c1",
|
|
323
|
+
"effect-smol": "#a3be8c",
|
|
324
|
+
"opencode-console": "#b48ead",
|
|
325
|
+
opencontrol: "#d08770",
|
|
326
|
+
default: "#88c0d0",
|
|
327
|
+
},
|
|
328
|
+
diff: {
|
|
329
|
+
addedBg: "#334033",
|
|
330
|
+
removedBg: "#433238",
|
|
331
|
+
contextBg: "transparent",
|
|
332
|
+
lineNumberBg: "#242933",
|
|
333
|
+
addedLineNumberBg: "#303d31",
|
|
334
|
+
removedLineNumberBg: "#3f3036",
|
|
335
|
+
},
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
const draculaColors: ColorPalette = {
|
|
339
|
+
background: "#282a36",
|
|
340
|
+
panel: "#21222c",
|
|
341
|
+
footer: "#343746",
|
|
342
|
+
modalBackground: "#343746",
|
|
343
|
+
text: "#f8f8f2",
|
|
344
|
+
muted: "#8f94b8",
|
|
345
|
+
separator: "#4f5268",
|
|
346
|
+
accent: "#bd93f9",
|
|
347
|
+
inlineCode: "#ff79c6",
|
|
348
|
+
error: "#ff5555",
|
|
349
|
+
selectedBg: "#44475a",
|
|
350
|
+
selectedText: "#f8f8f2",
|
|
351
|
+
count: "#ffb86c",
|
|
352
|
+
status: {
|
|
353
|
+
draft: "#f1fa8c",
|
|
354
|
+
approved: "#50fa7b",
|
|
355
|
+
changes: "#ff5555",
|
|
356
|
+
review: "#8be9fd",
|
|
357
|
+
none: "#8f94b8",
|
|
358
|
+
passing: "#50fa7b",
|
|
359
|
+
pending: "#f1fa8c",
|
|
360
|
+
failing: "#ff5555",
|
|
361
|
+
},
|
|
362
|
+
repos: {
|
|
363
|
+
opencode: "#8be9fd",
|
|
364
|
+
"effect-smol": "#50fa7b",
|
|
365
|
+
"opencode-console": "#ff79c6",
|
|
366
|
+
opencontrol: "#ffb86c",
|
|
367
|
+
default: "#bd93f9",
|
|
368
|
+
},
|
|
369
|
+
diff: {
|
|
370
|
+
addedBg: "#203a29",
|
|
371
|
+
removedBg: "#43272f",
|
|
372
|
+
contextBg: "transparent",
|
|
373
|
+
lineNumberBg: "#21222c",
|
|
374
|
+
addedLineNumberBg: "#1d3627",
|
|
375
|
+
removedLineNumberBg: "#3d252c",
|
|
376
|
+
},
|
|
377
|
+
}
|
|
378
|
+
|
|
170
379
|
export const themeDefinitions: readonly ThemeDefinition[] = [
|
|
171
380
|
{ id: "ghui", name: "GHUI", description: "Warm parchment accents on a deep slate background", colors: ghuiColors },
|
|
172
381
|
{ id: "tokyo-night", name: "Tokyo Night", description: "Cool indigo surfaces with neon editor accents", colors: tokyoNightColors },
|
|
382
|
+
{ id: "catppuccin", name: "Catppuccin", description: "Mocha lavender, peach, and soft pastel contrast", colors: catppuccinColors },
|
|
383
|
+
{ id: "rose-pine", name: "Rose Pine", description: "Muted rose, pine, and gold on dusky violet", colors: rosePineColors },
|
|
384
|
+
{ id: "gruvbox", name: "Gruvbox", description: "Retro warm earth tones with punchy semantic accents", colors: gruvboxColors },
|
|
385
|
+
{ id: "nord", name: "Nord", description: "Arctic blue-gray surfaces with frosty accents", colors: nordColors },
|
|
386
|
+
{ id: "dracula", name: "Dracula", description: "High-contrast purple, pink, cyan, and green", colors: draculaColors },
|
|
173
387
|
{ id: "opencode", name: "OpenCode", description: "Charcoal panels with peach, violet, and blue highlights", colors: opencodeColors },
|
|
174
388
|
] as const
|
|
175
389
|
|
|
@@ -180,6 +394,7 @@ export const colors: ColorPalette = { ...ghuiColors }
|
|
|
180
394
|
export const getThemeDefinition = (id: ThemeId) => themeDefinitions.find((theme) => theme.id === id) ?? themeDefinitions[0]!
|
|
181
395
|
|
|
182
396
|
export const setActiveTheme = (id: ThemeId) => {
|
|
397
|
+
if (activeTheme.id === id) return
|
|
183
398
|
activeTheme = getThemeDefinition(id)
|
|
184
399
|
Object.assign(colors, activeTheme.colors)
|
|
185
400
|
}
|
package/src/ui/modals.tsx
CHANGED
|
@@ -27,7 +27,6 @@ export interface MergeModalState {
|
|
|
27
27
|
|
|
28
28
|
export interface ThemeModalState {
|
|
29
29
|
readonly open: boolean
|
|
30
|
-
readonly selectedIndex: number
|
|
31
30
|
readonly initialThemeId: ThemeId
|
|
32
31
|
}
|
|
33
32
|
|
|
@@ -53,7 +52,6 @@ export const initialMergeModalState: MergeModalState = {
|
|
|
53
52
|
|
|
54
53
|
export const initialThemeModalState: ThemeModalState = {
|
|
55
54
|
open: false,
|
|
56
|
-
selectedIndex: 0,
|
|
57
55
|
initialThemeId: "ghui",
|
|
58
56
|
}
|
|
59
57
|
|
|
@@ -279,7 +277,8 @@ export const ThemeModal = ({
|
|
|
279
277
|
const contentWidth = Math.max(14, innerWidth - 2)
|
|
280
278
|
const rowWidth = innerWidth
|
|
281
279
|
const maxVisible = Math.max(1, modalHeight - 7)
|
|
282
|
-
const
|
|
280
|
+
const activeIndex = themeDefinitions.findIndex((theme) => theme.id === activeThemeId)
|
|
281
|
+
const selectedIndex = Math.max(0, activeIndex)
|
|
283
282
|
const selectedTheme = themeDefinitions[selectedIndex]!
|
|
284
283
|
const scrollStart = Math.min(
|
|
285
284
|
Math.max(0, themeDefinitions.length - maxVisible),
|