mirror of
https://github.com/usebruno/bruno.git
synced 2026-06-25 21:55:49 +00:00
feat: implement dynamic terminal theming based on app theme (#6812)
- Added a function to build terminal themes from the app's current theme. - Updated terminal creation and rendering functions to accept and apply the dynamic theme. - Implemented a useEffect hook to update terminal themes when the app theme changes.
This commit is contained in:
committed by
GitHub
parent
89a0494e7e
commit
1fc703e4e3
@@ -2,10 +2,37 @@ import React, { useRef, useEffect, useState, useCallback } from 'react';
|
||||
import { Terminal } from '@xterm/xterm';
|
||||
import { FitAddon } from '@xterm/addon-fit';
|
||||
import { IconTerminal2, IconPlus } from '@tabler/icons';
|
||||
import { useTheme } from 'providers/Theme';
|
||||
import StyledWrapper from './StyledWrapper';
|
||||
import SessionList from './SessionList';
|
||||
import '@xterm/xterm/css/xterm.css';
|
||||
|
||||
// Build xterm.js theme from app theme
|
||||
const getTerminalTheme = (theme) => {
|
||||
return {
|
||||
background: theme.console.bg,
|
||||
foreground: theme.console.messageColor,
|
||||
cursor: theme.console.messageColor,
|
||||
selectionBackground: theme.status.info.background,
|
||||
black: theme.background.base,
|
||||
red: theme.status.danger.text,
|
||||
green: theme.status.success.text,
|
||||
yellow: theme.status.warning.text,
|
||||
blue: theme.status.info.text,
|
||||
magenta: theme.colors.text.purple,
|
||||
cyan: theme.codemirror.variable.prompt,
|
||||
white: theme.text,
|
||||
brightBlack: theme.colors.text.muted,
|
||||
brightRed: theme.status.danger.text,
|
||||
brightGreen: theme.status.success.text,
|
||||
brightYellow: theme.status.warning.text,
|
||||
brightBlue: theme.status.info.text,
|
||||
brightMagenta: theme.colors.text.purple,
|
||||
brightCyan: theme.codemirror.variable.prompt,
|
||||
brightWhite: theme.text
|
||||
};
|
||||
};
|
||||
|
||||
// Terminal instances per session - Map<sessionId, { terminal, fitAddon, inputDisposable, resizeDisposable }>
|
||||
const terminalInstances = new Map();
|
||||
|
||||
@@ -33,7 +60,7 @@ const ensureParkingHost = () => {
|
||||
return parkingHost;
|
||||
};
|
||||
|
||||
const createTerminalForSession = (sessionId) => {
|
||||
const createTerminalForSession = (sessionId, terminalTheme) => {
|
||||
if (terminalInstances.has(sessionId)) {
|
||||
return terminalInstances.get(sessionId);
|
||||
}
|
||||
@@ -42,28 +69,7 @@ const createTerminalForSession = (sessionId) => {
|
||||
cursorBlink: true,
|
||||
fontSize: 14,
|
||||
fontFamily: 'Menlo, Monaco, "Courier New", monospace',
|
||||
theme: {
|
||||
background: '#1e1e1e',
|
||||
foreground: '#d4d4d4',
|
||||
cursor: '#d4d4d4',
|
||||
selection: '#264f78',
|
||||
black: '#1e1e1e',
|
||||
red: '#f14c4c',
|
||||
green: '#23d18b',
|
||||
yellow: '#f5f543',
|
||||
blue: '#3b8eea',
|
||||
magenta: '#d670d6',
|
||||
cyan: '#29b8db',
|
||||
white: '#e5e5e5',
|
||||
brightBlack: '#666666',
|
||||
brightRed: '#f14c4c',
|
||||
brightGreen: '#23d18b',
|
||||
brightYellow: '#f5f543',
|
||||
brightBlue: '#3b8eea',
|
||||
brightMagenta: '#d670d6',
|
||||
brightCyan: '#29b8db',
|
||||
brightWhite: '#e5e5e5'
|
||||
},
|
||||
theme: terminalTheme,
|
||||
allowProposedApi: true
|
||||
});
|
||||
|
||||
@@ -156,10 +162,10 @@ const cleanupTerminalInstance = (sessionId) => {
|
||||
}
|
||||
};
|
||||
|
||||
const openTerminalIntoContainer = async (container, sessionId) => {
|
||||
const openTerminalIntoContainer = async (container, sessionId, terminalTheme) => {
|
||||
if (!container || !sessionId) return;
|
||||
|
||||
const instance = createTerminalForSession(sessionId);
|
||||
const instance = createTerminalForSession(sessionId, terminalTheme);
|
||||
const { terminal, fitAddon } = instance;
|
||||
|
||||
if (!terminal.element) {
|
||||
@@ -212,6 +218,8 @@ const TerminalTab = () => {
|
||||
const [sessions, setSessions] = useState([]);
|
||||
const [activeSessionId, setActiveSessionId] = useState(null);
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
const { theme } = useTheme();
|
||||
const terminalTheme = getTerminalTheme(theme);
|
||||
|
||||
// Load sessions list
|
||||
const loadSessions = useCallback(async (currentActiveSessionId = null) => {
|
||||
@@ -355,6 +363,15 @@ const TerminalTab = () => {
|
||||
};
|
||||
}, []);
|
||||
|
||||
// Update all terminal themes when app theme changes
|
||||
useEffect(() => {
|
||||
terminalInstances.forEach((instance) => {
|
||||
if (instance.terminal) {
|
||||
instance.terminal.options.theme = terminalTheme;
|
||||
}
|
||||
});
|
||||
}, [theme.mode]);
|
||||
|
||||
// Handle terminal display for active session
|
||||
useEffect(() => {
|
||||
if (!activeSessionId || !terminalRef.current) return;
|
||||
@@ -362,7 +379,7 @@ const TerminalTab = () => {
|
||||
let mounted = true;
|
||||
|
||||
const setupTerminal = async () => {
|
||||
await openTerminalIntoContainer(terminalRef.current, activeSessionId);
|
||||
await openTerminalIntoContainer(terminalRef.current, activeSessionId, terminalTheme);
|
||||
|
||||
if (mounted) {
|
||||
const instance = terminalInstances.get(activeSessionId);
|
||||
|
||||
Reference in New Issue
Block a user