Add vertical resizer for voice panel

This commit is contained in:
dimitrievgs 2026-04-30 19:32:12 +03:00
parent aee60c1ac2
commit 2dd033a010
2 changed files with 89 additions and 36 deletions

View File

@ -757,11 +757,39 @@
border-top: 1px solid var(--background-modifier-border);
}
.voice-panel-container {
.voice-panel-resizer {
height: 4px;
width: 100%;
cursor: ns-resize;
background-color: var(--divider-color);
flex-shrink: 0;
z-index: 10;
}
.voice-panel-resizer:hover {
background-color: var(--interactive-accent);
}
/* Убедимся, что нижняя панель не перекрывает контент */
.voice-panel-fixed-bottom {
display: flex;
flex-direction: column;
min-height: 50px; /* Минимальная доступная высота */
}
.voice-panel-container {
height: 100%;
padding: 5px;
display: flex;
flex-direction: column;
}
.voice-body {
flex: 1;
overflow-y: auto;
background-color: var(--background-primary);
border: 1px inset var(--background-modifier-border);
margin: 4px;
padding: 8px;
}
.voice-header {
@ -791,16 +819,6 @@
border-bottom: 2px solid var(--text-accent);
}
.voice-body {
flex: 1;
overflow-y: auto;
font-size: 12px;
font-family: var(--font-monospace);
padding: 10px;
background-color: var(--background-primary);
white-space: pre-wrap; /* Чтобы транскрибация не уходила в одну строку */
}
/* Кнопки управления голосом */
.v-controls button {
margin-right: 5px;

View File

@ -91,50 +91,85 @@ export class GraphView extends ItemView {
const container = this.containerEl.children[1] as HTMLElement;
container.empty();
// 1. Основной контейнер - теперь вертикальный стек
const mainContainer = container.createDiv('llm-agent-graph-main');
mainContainer.style.cssText = `
display: flex;
flex-direction: column; /* Элементы кладутся друг под друга */
flex-direction: column;
height: 100%;
width: 100%;
overflow: hidden;
`;
// 2. Верхняя часть (История + Граф)
// 1. Верхняя часть
const upperContent = mainContainer.createDiv('upper-content-wrapper');
upperContent.style.cssText = `
display: flex;
flex-direction: row; /* Элементы бок о бок */
flex: 1; /* Занимает всё свободное место (около 75-80%) */
flex-direction: row;
flex: 1;
width: 100%;
min-height: 0; /* Важно для корректного скролла внутри */
min-height: 0;
`;
// 3. Левая панель для истории (внутри верхней части)
this.historyContainer = upperContent.createDiv('llm-agent-history-sidebar');
this.historyContainer.classList.add(this.isHistoryCollapsed ? 'collapsed' : 'expanded');
// 4. Правая панель для графа (внутри верхней части)
this.graphContainer = upperContent.createDiv('llm-agent-graph-container');
this.graphContainer.style.cssText = `
flex: 1;
position: relative;
background-color: var(--background-primary);
`;
this.graphContainer.style.cssText = `flex: 1; position: relative; background-color: var(--background-primary);`;
// 5. Контейнер для голосовой панели (строго ВНИЗУ)
const voiceContainer = mainContainer.createDiv('voice-panel-fixed-bottom');
voiceContainer.style.cssText = `
height: 200px; /* Фиксированная высота или % */
// 2. РАЗДЕЛИТЕЛЬ (Resizer)
const resizer = mainContainer.createDiv('voice-panel-resizer');
resizer.style.cssText = `
height: 4px;
width: 100%;
border-top: 1px solid var(--divider-color);
background-color: var(--background-secondary);
overflow: hidden;
flex-shrink: 0; /* Не дает панели сжиматься */
cursor: ns-resize;
background-color: var(--divider-color);
flex-shrink: 0;
transition: background-color 0.2s;
`;
// Инициализация компонентов
// 3. Нижняя панель
const voiceContainer = mainContainer.createDiv('voice-panel-fixed-bottom');
let initialHeight = 150; // Высота по умолчанию
voiceContainer.style.cssText = `
height: ${initialHeight}px;
width: 100%;
background-color: var(--background-secondary);
overflow: hidden;
flex-shrink: 0;
`;
// ЛОГИКА ИЗМЕНЕНИЯ ВЫСОТЫ
let isResizing = false;
resizer.addEventListener('mousedown', (e) => {
isResizing = true;
document.body.style.cursor = 'ns-resize';
// Чтобы iframe/график не перехватывали события мыши
mainContainer.style.pointerEvents = 'none';
});
document.addEventListener('mousemove', (e) => {
if (!isResizing) return;
// Вычисляем расстояние от верха контейнера
const containerRect = mainContainer.getBoundingClientRect();
const newHeight = containerRect.bottom - e.clientY;
// Ограничения (мин 50px, макс 70% высоты)
if (newHeight > 50 && newHeight < containerRect.height * 0.7) {
voiceContainer.style.height = `${newHeight}px`;
}
});
document.addEventListener('mouseup', () => {
if (isResizing) {
isResizing = false;
document.body.style.cursor = 'default';
mainContainer.style.pointerEvents = 'all';
}
});
// Инициализация остальных компонентов
this.historyPanel = new HistoryPanel(
this.historyContainer,
{ graphs: this.graphsList, eventBus: this.plugin.eventBus },