diff --git a/src/components/ChatPanel.ts b/src/components/ChatPanel.ts index 3f5383b..ae0ee30 100644 --- a/src/components/ChatPanel.ts +++ b/src/components/ChatPanel.ts @@ -38,6 +38,8 @@ export class ChatPanel { selectedModel: string; customPromptIndicator: HTMLSpanElement | null = null; currentStreamingNodeId: string | null; + + branchChatBtn: HTMLButtonElement; stopButton: HTMLButtonElement; scrollToBottomBtn: HTMLButtonElement; scrollToTopBtn: HTMLButtonElement; @@ -457,6 +459,7 @@ export class ChatPanel { async updateHistory(newHistory: ChatHistoryItem[]): Promise { this.chatHistory = newHistory; await this.renderHistory(); + this.updateScrollButtonsVisibility(); // НОВОЕ: проверяем видимость кнопок } /** @@ -614,6 +617,10 @@ export class ChatPanel {
+ + @@ -698,8 +705,9 @@ export class ChatPanel { this.modelSelectButton = this.container.querySelector('#model-select-button') as HTMLButtonElement; this.modelDropdown = this.container.querySelector('#model-dropdown') as HTMLDivElement; this.customPromptIndicator = this.container.querySelector('#custom-prompt-indicator') as HTMLSpanElement; - this.stopButton = this.container.querySelector('#stop-button') as HTMLButtonElement; + this.branchChatBtn = this.container.querySelector('#branch-chat-btn') as HTMLButtonElement; + this.stopButton = this.container.querySelector('#stop-button') as HTMLButtonElement; this.scrollToTopBtn = this.container.querySelector('#scroll-to-top-btn') as HTMLButtonElement; this.scrollToBottomBtn = this.container.querySelector('#scroll-to-bottom-btn') as HTMLButtonElement; @@ -813,6 +821,10 @@ export class ChatPanel { this.props.plugin.eventBus.emit('stop-all-streams'); }); + this.branchChatBtn.addEventListener('click', () => { + this.props.plugin.eventBus.emit('start-new-independent-chat'); + }); + // Подписка на изменение стримов this.props.plugin.eventBus.on('global-stream-state-changed', (isStreaming: boolean) => { this.hasGlobalStreams = isStreaming; @@ -1730,14 +1742,16 @@ export class ChatPanel { if (!this.cachedScrollContainer || !this.cachedBtnWrapper) return; const hasScrollbar = this.cachedScrollContainer.scrollHeight > (this.cachedScrollContainer.clientHeight + 2); + const hasHistory = this.chatHistory && this.chatHistory.length > 0; // Управляем видимостью кнопок скролла (скрываем их индивидуально) this.scrollToTopBtn.style.display = hasScrollbar ? 'flex' : 'none'; this.scrollToBottomBtn.style.display = hasScrollbar ? 'flex' : 'none'; this.globalStopBtn.style.display = this.hasGlobalStreams ? 'flex' : 'none'; + this.branchChatBtn.style.display = hasHistory ? 'flex' : 'none'; // Обертка видна, если есть либо скроллбар, либо активный стрим - if (hasScrollbar || this.hasGlobalStreams) { + if (hasScrollbar || this.hasGlobalStreams || hasHistory) { this.cachedBtnWrapper.classList.add('is-visible'); } else { this.cachedBtnWrapper.classList.remove('is-visible'); diff --git a/src/css/styles.css b/src/css/styles.css index 73c73f9..31c339e 100644 --- a/src/css/styles.css +++ b/src/css/styles.css @@ -528,7 +528,8 @@ /* Добавить общий стиль для обеих кнопок и специфичный для новой */ .scroll-to-bottom-btn, -.scroll-to-top-btn { +.scroll-to-top-btn, +.branch-chat-btn { pointer-events: auto; border: 2px solid var(--background-primary); border-radius: 50%; @@ -557,7 +558,8 @@ } .scroll-to-bottom-btn:hover, -.scroll-to-top-btn:hover { +.scroll-to-top-btn:hover, +.branch-chat-btn:hover { opacity: 1; transform: scale(1.1); box-shadow: 0 6px 20px rgba(0, 0, 0, 0.4); @@ -565,13 +567,15 @@ } .scroll-to-bottom-btn:active, -.scroll-to-top-btn:active { +.scroll-to-top-btn:active, +.branch-chat-btn:active { transform: scale(0.95); } /* Иконки кнопок */ .scroll-to-bottom-btn svg, -.scroll-to-top-btn svg { +.scroll-to-top-btn svg, +.branch-chat-btn svg { width: 18px; height: 18px; stroke-width: 3px;