From 303ae133a4845990facb52dfe78829aff52dd4bc Mon Sep 17 00:00:00 2001 From: STetsing <41009393+STetsing@users.noreply.github.com> Date: Mon, 6 Jan 2025 16:05:20 +0100 Subject: [PATCH 1/5] overrided the nlux clipboard button --- .../remix-ai/src/lib/components/Default.tsx | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/libs/remix-ui/remix-ai/src/lib/components/Default.tsx b/libs/remix-ui/remix-ai/src/lib/components/Default.tsx index 50a50d1e3d2..2d36e01e86e 100644 --- a/libs/remix-ui/remix-ai/src/lib/components/Default.tsx +++ b/libs/remix-ui/remix-ai/src/lib/components/Default.tsx @@ -1,9 +1,8 @@ import React from 'react' import '../remix-ai.css' -import { DefaultModels, GenerationParams, ChatHistory, HandleStreamResponse, HandleSimpleResponse } from '@remix/remix-ai-core'; +import { DefaultModels, GenerationParams, ChatHistory, HandleStreamResponse } from '@remix/remix-ai-core'; import { ConversationStarter, StreamSend, StreamingAdapterObserver, useAiChatApi } from '@nlux/react'; import { AiChat, useAsStreamAdapter, ChatItem } from '@nlux/react'; -import { JsonStreamParser } from '@remix/remix-ai-core'; import { user, assistantAvatar } from './personas'; import { highlighter } from '@nlux/highlighter' import './color.css' @@ -32,6 +31,18 @@ export const Default = (props) => { observer.next(' ') // Add a space to flush the last message ChatHistory.pushHistory(prompt, result) observer.complete() + const codeBlocks = document.getElementsByClassName('code-block') + + // override copy button functionality + Array.from(codeBlocks).forEach((block) => { + // only 1 copy button per code block + const copyButton = document.getElementsByClassName('nlux-comp-copyButton') + copyButton[0].addEventListener('click', async () => { + console.log('nlux copy button clicked'); + const text = block.textContent; //|| block.innerText; + await navigator.clipboard.writeText(block.textContent); + }); + }) } ) else { @@ -73,7 +84,7 @@ export const Default = (props) => { submitShortcut: 'Enter', hideStopButton: false, }} - messageOptions={{ showCodeBlockCopyButton: false, + messageOptions={{ showCodeBlockCopyButton: true, editableUserMessages: true, streamingAnimationSpeed: 2, waitTimeBeforeStreamCompletion: 1000, From bddb0ea1a3b88c33e007ee5fc3f83f1d299343b9 Mon Sep 17 00:00:00 2001 From: STetsing <41009393+STetsing@users.noreply.github.com> Date: Mon, 6 Jan 2025 17:22:43 +0100 Subject: [PATCH 2/5] multiple buttons --- .../remix-ai/src/lib/components/Default.tsx | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/libs/remix-ui/remix-ai/src/lib/components/Default.tsx b/libs/remix-ui/remix-ai/src/lib/components/Default.tsx index 2d36e01e86e..080400ddfdf 100644 --- a/libs/remix-ui/remix-ai/src/lib/components/Default.tsx +++ b/libs/remix-ui/remix-ai/src/lib/components/Default.tsx @@ -33,15 +33,13 @@ export const Default = (props) => { observer.complete() const codeBlocks = document.getElementsByClassName('code-block') - // override copy button functionality Array.from(codeBlocks).forEach((block) => { - // only 1 copy button per code block - const copyButton = document.getElementsByClassName('nlux-comp-copyButton') - copyButton[0].addEventListener('click', async () => { - console.log('nlux copy button clicked'); - const text = block.textContent; //|| block.innerText; - await navigator.clipboard.writeText(block.textContent); - }); + const copyButtons = block.getElementsByClassName('nlux-comp-copyButton'); + Array.from(copyButtons).forEach((cp_btn) => { + cp_btn.addEventListener('click', async () => { + await navigator.clipboard.writeText(block.textContent); + }); + }) }) } ) From 66405d2f3e58cf0e62852afff94372d916500997 Mon Sep 17 00:00:00 2001 From: STetsing <41009393+STetsing@users.noreply.github.com> Date: Mon, 6 Jan 2025 17:29:29 +0100 Subject: [PATCH 3/5] rm multiple same listeners --- libs/remix-ui/remix-ai/src/lib/components/Default.tsx | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libs/remix-ui/remix-ai/src/lib/components/Default.tsx b/libs/remix-ui/remix-ai/src/lib/components/Default.tsx index 080400ddfdf..ae1a376d938 100644 --- a/libs/remix-ui/remix-ai/src/lib/components/Default.tsx +++ b/libs/remix-ui/remix-ai/src/lib/components/Default.tsx @@ -36,6 +36,9 @@ export const Default = (props) => { Array.from(codeBlocks).forEach((block) => { const copyButtons = block.getElementsByClassName('nlux-comp-copyButton'); Array.from(copyButtons).forEach((cp_btn) => { + // remove click event listener if existing + cp_btn.removeEventListener('click', () => {}); + cp_btn.addEventListener('click', async () => { await navigator.clipboard.writeText(block.textContent); }); From 73cc89a3b75d14e4c5e0ecd9245b49be84e85c95 Mon Sep 17 00:00:00 2001 From: STetsing <41009393+STetsing@users.noreply.github.com> Date: Mon, 6 Jan 2025 17:35:46 +0100 Subject: [PATCH 4/5] minor --- .../remix-ai/src/lib/components/Default.tsx | 28 ++++++++++--------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/libs/remix-ui/remix-ai/src/lib/components/Default.tsx b/libs/remix-ui/remix-ai/src/lib/components/Default.tsx index ae1a376d938..e82504e8507 100644 --- a/libs/remix-ui/remix-ai/src/lib/components/Default.tsx +++ b/libs/remix-ui/remix-ai/src/lib/components/Default.tsx @@ -11,6 +11,19 @@ import '@nlux/themes/unstyled.css'; export let ChatApi = null export const Default = (props) => { + + const HandleCopyToClipboard = () => { + const codeBlocks = document.getElementsByClassName('code-block') + Array.from(codeBlocks).forEach((block) => { + const copyButtons = block.getElementsByClassName('nlux-comp-copyButton') + Array.from(copyButtons).forEach((cp_btn) => { + cp_btn.removeEventListener('click', () => {}) + cp_btn.addEventListener('click', async () => { + await navigator.clipboard.writeText(block.textContent) + }) + }) + }) + } const send: StreamSend = async ( prompt: string, observer: StreamingAdapterObserver, @@ -31,24 +44,13 @@ export const Default = (props) => { observer.next(' ') // Add a space to flush the last message ChatHistory.pushHistory(prompt, result) observer.complete() - const codeBlocks = document.getElementsByClassName('code-block') - - Array.from(codeBlocks).forEach((block) => { - const copyButtons = block.getElementsByClassName('nlux-comp-copyButton'); - Array.from(copyButtons).forEach((cp_btn) => { - // remove click event listener if existing - cp_btn.removeEventListener('click', () => {}); - - cp_btn.addEventListener('click', async () => { - await navigator.clipboard.writeText(block.textContent); - }); - }) - }) + HandleCopyToClipboard() } ) else { observer.next(response) observer.complete() + HandleCopyToClipboard() } }; From eda99000ca0ebd5f37f1f61148d29edcc641bc3a Mon Sep 17 00:00:00 2001 From: STetsing <41009393+STetsing@users.noreply.github.com> Date: Mon, 6 Jan 2025 20:08:52 +0100 Subject: [PATCH 5/5] effect on streaming --- .../remix-ai/src/lib/components/Default.tsx | 32 +++++++++++++------ 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/libs/remix-ui/remix-ai/src/lib/components/Default.tsx b/libs/remix-ui/remix-ai/src/lib/components/Default.tsx index e82504e8507..b18d42bfdd0 100644 --- a/libs/remix-ui/remix-ai/src/lib/components/Default.tsx +++ b/libs/remix-ui/remix-ai/src/lib/components/Default.tsx @@ -1,4 +1,4 @@ -import React from 'react' +import React, { useState, useEffect } from 'react' import '../remix-ai.css' import { DefaultModels, GenerationParams, ChatHistory, HandleStreamResponse } from '@remix/remix-ai-core'; import { ConversationStarter, StreamSend, StreamingAdapterObserver, useAiChatApi } from '@nlux/react'; @@ -7,28 +7,40 @@ import { user, assistantAvatar } from './personas'; import { highlighter } from '@nlux/highlighter' import './color.css' import '@nlux/themes/unstyled.css'; +import copy from 'copy-to-clipboard' export let ChatApi = null export const Default = (props) => { + const [is_streaming, setIS_streaming] = useState(false) const HandleCopyToClipboard = () => { - const codeBlocks = document.getElementsByClassName('code-block') + const markdown = document.getElementsByClassName('nlux-chatSegments-container') + if (markdown.length < 1) return + + const codeBlocks = markdown[0].getElementsByClassName('code-block') Array.from(codeBlocks).forEach((block) => { const copyButtons = block.getElementsByClassName('nlux-comp-copyButton') Array.from(copyButtons).forEach((cp_btn) => { - cp_btn.removeEventListener('click', () => {}) - cp_btn.addEventListener('click', async () => { - await navigator.clipboard.writeText(block.textContent) - }) + const hdlr = async () => { + copy(block.textContent) + } + cp_btn.removeEventListener('click', async() => { hdlr() }) + cp_btn.addEventListener('click', async () => { hdlr() }) }) }) } + + useEffect(() => { + HandleCopyToClipboard(); + }, [is_streaming]); + const send: StreamSend = async ( prompt: string, observer: StreamingAdapterObserver, ) => { GenerationParams.stream_result = true + setIS_streaming(true) GenerationParams.return_stream_response = GenerationParams.stream_result let response = null @@ -44,15 +56,15 @@ export const Default = (props) => { observer.next(' ') // Add a space to flush the last message ChatHistory.pushHistory(prompt, result) observer.complete() - HandleCopyToClipboard() + setTimeout(() => { setIS_streaming(false) }, 1000) } ) else { observer.next(response) observer.complete() - HandleCopyToClipboard() - } + setTimeout(() => { setIS_streaming(false) }, 1000) + } }; ChatApi = useAiChatApi(); const conversationStarters: ConversationStarter[] = [ @@ -89,7 +101,7 @@ export const Default = (props) => { }} messageOptions={{ showCodeBlockCopyButton: true, editableUserMessages: true, - streamingAnimationSpeed: 2, + streamingAnimationSpeed: 1, waitTimeBeforeStreamCompletion: 1000, syntaxHighlighter: highlighter }}