OvidijusParsiunas / deep-chat

Fully customizable AI chatbot component for your website
https://deepchat.dev
MIT License
1.43k stars 218 forks source link

HTML message button actions #102

Closed rvangari96 closed 8 months ago

rvangari96 commented 8 months ago

For the screenshot below. My functionality is to update like, dislike and show query used to generate the chat.

image

I written the code below but for the like, dislike, and show query buttons click is not working, getting function is not defined. Could you please help on how to fix this issue.

<DeepChat className ref={chatRef} style={{ borderRadius: "10px", zIndex: 1, height: "calc(100vh - 170px)", width: "36rem", }} avatars={{ default: { styles: { position: "left" } }, ai: { src: "/profile/images/openAIGreyLogo.svg" }, user: { src: "/profile/images/23735.png" }, }} messageStyles={{ default: { shared: { innerContainer: { width: "95%" }, bubble: { maxWidth: "100%", backgroundColor: "unset", marginTop: "10px", marginBottom: "10px", fontSize: "1rem", }, }, user: { bubble: { marginLeft: "0px", color: "black", }, }, ai: { outerContainer: { backgroundColor: "rgba(247,247,248)", borderTop: "1px solid rgba(0,0,0,.1)", borderBottom: "1px solid rgba(0,0,0,.1)", }, }, }, }} textInput={{ placeholder: { text: "Welcome to DocuFlow..!" } }} audio={true} images={true} gifs={true} camera={true} microphone={true} mixedFiles={true} request={{ url: process.env.REACT_APP_API_URL + 'chat/execute', handler: async (body, signals) => { try { const response = { data: { "query": "MEJrVmh3bWZrOG1qQ2c4ZC92RERlY1FFWFFSNk9iWEMyR01FcTY5NVMrSDRhK3MrUmpVUWdrN0EyNHhlSExXZm1VOGl0RzU3WUxuSGY0WndBRU03dVNxMzROYmc3OTZzM0ZYOG52dUpPRmJCRUVhWjUyZ2xwaDdKMERjYXNnWDNRNUNzcSs4SG9KN05EZzlIV1Zqd3c4ZXQvT1BUNS9uSUN1bGpxZVh5RlQ4eXZQMkRGSW1Ucnl5N2hadXo3K3Q4aHRtRUp0eE1hWEk3MEYzeU16cWJIdjY4VE1EaGlBbjZjY0FGS3ZZeFFOUnpnMys1aFZlaG1Cd2NHN2VKb1lzRUVGTXNqeVVKRlE4NU1ZbmdQVzB2c09LZmI5THBPQi9xS0pWT3ppbXh1cjBCcUNLSjB2Y0xpZkVxTnFoeG9BOS9NVm94OHdqYWJpc3l2L094YS9qYzhVV1FFc2JuU1VoK0xabU1aVzFHWGlMTzZBK3dQUUZUSVN6WGpzS3U2QVR2VjEyUFM1c2JtSE51aGpuL09VM2ZnTXE2VzFxYjUzNUJtOHRQVlo0WHNmb1YwS3JJdGxlc2pCZmVFYktET0lxL1dXQmJCdEloT2FSVzM5eVRMdU9wMlN0N3BhR1lYYVpPYmtQU2dDUjg2eVQ3d3ZEMTlzRmdHY3JZVGhoRjAwQXhFWlZvcFViSUs1VlVFZ0JkOWxBczVMcm9yNTZKKzV5dld2T1hsdHUycWp4Um5uL2ppOE5MRVh6ckRkV2pHSnVJQXBJRWsvMEpYaVRjUUpUdVN1c0xGcWJVeDlMK2NPMytzclZHMDhGWVRzL05JUVZCdEdKWmREdFpCa1Y2VmFyUmE0LzBHbGlNR0RUL0ZNbThQb2dSeGF6TWhmR0hnZG9wK3FDYS9jbFJheHdHcWhRS0Y4by80aFJ1VEhockJ4R29VaS9DbmEwREkzUk9NMjRhaC9HZ3NVQ2xxall1ek8vSHJPN0FROGJuT0JoS25MMk95UG9ta3lpYXAvTitFUExySEdsK3N6bmJmQjc5UVhsVEZlekFqQVcrYjQ4d1p1aE1FMGY2d0NUSEtNMlUzY015ejMvTkxTMzZhN0Jpa0VQUkVuVVpnWkhlVnB1WS8zK0VNY2o5VnVlY05EaC9oaDhSQUtsQ0NVK1pjMTdwUDU2M0lEQW03UXZ5WmNDQ0ROS3RKbFdETXViaUVmVU9yTStMenEvdUlqN0RxWmhBdW9wVGlkdzhsU3ZSeGN5ZVlmK1hoc0JReGhsWVorbi85MHg0QWpXdy84ZWpld0l4Yk81emprdmFxWHRXc1h4Y252c1FxeUhaVFRZdVZCbUFqdC90V0FoQmdjVGNXR3M0YnM4elZqK3piaGRTOTErb2ZyRlJyVjRzZWhVWk1DdjNlTm9La0lNTnFGNkVMRks2Q252QzF1NGhIaXB6RFlYOWZJVEdlWHp5Z1QrdnVsaUtSMSsvNkFmMXJYWU1aS1JQRmw4bVVaV2ZIV3FEL3hZT0J0NDRXdGxJNEhPeEQ1UXVKdUI5cC9kNHdWU2lTcG9SV3RUeFFqYWdOSmczWm5NU0Nhd0k2QlRCQUhvSVpJaytOcU5nVy9xNmNvV054dElHWC9ocDh6Z0VDQVE3TEcxb2Jqa0Mxb2wrdy9hN3RwS1p0WE1HMGM5dWtKeTJXZFBGVFFiYmtLTUhmOG1IWDg0WGExaWxzbWdiMjVNVE1BOUFTbkw3R2w2aE5CY3hnemRQYmxzc1VmemtUd0c4RHpwQ1B2Vm5uYk5hOHdyUjdxR3p5TlJ6ck5rRXEzMEVFNnNKdUwxN0VlYzZMV1ZhYzFQYVM4Snd5RVFvMHNUVmV5T2hiOFF6c3AvRzlxa3FzeU9BQkFuVGJjRGdvak1kSlNUbFp6dThZWEZpZnRqZUN5SnhPNkk4dXg4UWJpLzZ1akRDRmtHR1Ezb1BxcU8wbExuK2dnR0xOZ0RtUEhHZkR6LzZSa1ZjOTZRRU9YNzlod2pCbklqbUthMHp4MWk4bXkvNnUvVVR0UjNwVnZPY00wQ3BJbzErMUNoOUhEMC9ZUG5kYjFWNE1FVGNFSjBpN3dCWlY0M3RucCtQNjk3MnI4WFBLM2grMCtsLysrRTJQNVpmdENQTDYvOC9oU09uOFVwUVErelphZlZOTEhVK2xmdGhPK1lNeTB4WFB1dG5YU0ZxYUlyZ3hVWnVXMGZRdVRtcUZPSnlZWStncFFxWDMwUXZ4cFkvZHJIdVRnPT0=", "data": [ [ "vendorName", "count" ], [ null, 50 ], [ "PRECOAT METALS", 32 ], [ "DEMO - Sliced Invoices", 31 ], [ "Staples", 17 ], [ "SW SIZEMORE WELDING -INC-", 13 ] ] } } const chartResult = getChartType(body.messages[0].text.toLowerCase()); const chartType = chartResult.chartType; onSetCurrentQuery(body, response.data) if (chartType === "text") { signals.onResponse({ text: JSON.stringify(response.data.data), }); } else { const responseHtml =

`; signals.onResponse({ html: responseHtml }); } } catch (error) { console.error(error); } }, }} initialMessages={messages} onNewMessage={({ message, isInitial }) => { if (!isInitial) { messages.push(message); } }} />`
OvidijusParsiunas commented 8 months ago

Hi @rvangari96. I have reduced your code to the following and it appears to work fine for me. Does it work for you?

 <DeepChat
  request={{
    handler: async (body, signals) => {
      const responseHtml = `
        <div>
          <div style='display: flex; gap: 1rem; margin-bottom: 1rem;'>
            <img style="cursor: pointer; width: 1.2rem" onclick="(() => {console.log('upvote')})()" class="chat-feedback feedback-icon-positive" src="thumbsUp.svg" />
            <img style="cursor: pointer; width: 1.2rem" onclick="(() => {console.log('downvote')})()" class="chat-feedback feedback-icon-negative" src="thumbsDown.svg" />
            <button>Show query</button>
          </div>
        </div>`;
      signals.onResponse({html: responseHtml});
    },
  }}
/>
rvangari96 commented 8 months ago

Hi Ovidijus. Thank you for the quick response.

It's working when the console.log is added but when you call the actual declared function it is not working. Like below.

const upVote = () => { console.log("upvote") }

const downVote = () => { console.log("upvote") }

<DeepChat request={{ handler: async (body, signals) => { const responseHtml = `

`; signals.onResponse({html: responseHtml}); }, }} /> If you want I can share the complete code for understanding. On Mon, Jan 22, 2024 at 5:48 PM Ovidijus Parsiunas ***@***.***> wrote: > Hi @rvangari96 . I have reduced your code > to the following and it appears to work fine for me. Does it work for you? > > request={{ > handler: async (body, signals) => { > const responseHtml = ` >
>
> > > >
    </div>`;
  signals.onResponse({html: responseHtml});
},

}} />

— Reply to this email directly, view it on GitHub https://github.com/OvidijusParsiunas/deep-chat/issues/102#issuecomment-1903886960, or unsubscribe https://github.com/notifications/unsubscribe-auth/A4T2FDEI5YVVHE5PJ4J7LG3YPZKIJAVCNFSM6AAAAABCFCJMJ6VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTSMBTHA4DMOJWGA . You are receiving this because you were mentioned.Message ID: @.***>

-- Best Regards Rakesh Vangari +91 8985169219

OvidijusParsiunas commented 8 months ago

Ok, I see what you mean now.

To add specific events/styling to particular elements in the html response, you will need to use the htmlClassUtilities property.

So in your example, if we wanted to use the upVote function, we would use the following code:

const upVote = () => {
  console.log('upvote');
};

return (
  <DeepChat
    htmlClassUtilities={{
      'feedback-icon-positive': {
        events: {
          click: upVote,
        },
      },
    }}
    request={{
      handler: async (body, signals) => {
        const responseHtml = `
        <div>
          <div style='display: flex; gap: 1rem; margin-bottom: 1rem;'>
            <img style="cursor: pointer; width: 1.2rem" class="chat-feedback feedback-icon-positive"
src="thumbsUp.svg" />
          </div>
        </div>`;
        signals.onResponse({html: responseHtml});
      },
    }}
  />
);

We basically reference the function inside the events property for a particular element class. You can do the same for other elements. Let me know if this helps! Thanks.

rvangari96 commented 8 months ago

Wow, this worked.

I have a few questions. Can I disable the like button whenever it is clicked? Additionally, how can I display text when clicking on the 'show query' button in the same message? If I add a button to regenerate the response, and when I click on it, can I replace the existing message with a new response?

Thank you.

On Mon, Jan 22, 2024 at 6:13 PM Ovidijus Parsiunas @.***> wrote:

Ok, I see what you mean now.

To add specific events/styling to particular elements in the html response, you will need to use the htmlClassUtilities https://deepchat.dev/docs/messages/HTML#htmlClassUtilities property.

So in your example, if we wanted to use the upVote function, we would use the following code:

const upVote = () => { console.log('upvote'); };

return ( <DeepChat htmlClassUtilities={{ 'feedback-icon-positive': { events: { click: upVote, }, }, }} request={{ handler: async (body, signals) => { const responseHtml = `

`; signals.onResponse({html: responseHtml}); }, }} /> ); We basically reference the function inside the events for a particular element class. You can do the same for other elements. Let me know if this helps! Thanks. — Reply to this email directly, view it on GitHub , or unsubscribe . You are receiving this because you were mentioned.Message ID: ***@***.***>

-- Best Regards Rakesh Vangari +91 8985169219

OvidijusParsiunas commented 8 months ago

Everything that you have mentioned is possible, but possible through standard HTML/JavaScript practices rather than anything specific that Deep Chat offers.

When an event function is called, in this case a click event - it passes an event argument with it. This argument can be used to manipulate the target element and the elements around it.

E.g. the upVote function can be changed to the following, where the clicked element is extracted via the target property and we then proceed to change its styling - such as changing the background color to yellow (this is a TypeScript example and you can remove the types if you are using Vanilla JavaScript):

const upVote = (event: MouseEvent) => {
  const element = event.target as HTMLElement;
  if (element?.style) {
    element.style.backgroundColor = 'yellow';
  }
};

You can use this technique for changing the elements to exactly how you need them.

Another quick tip; you can traverse elements via the use of children and parentElement properties. Changing text can be done via the textContent. Image/SVG colors can be changed via the css filter property (you can also use this tool to get the color you prefer).

This is a little outside of the scope of Deep Chat, therefore I would encourage you to check other resources on how elements can be manipulated, but I am more than happy to answer Deep Chat related questions.

Thanks!

OvidijusParsiunas commented 8 months ago

Since the original problem has been resolved, I will be closing this issue now. However, if you have any other questions you are more than welcome to create a new issue.

Thankyou!

rvangari96 commented 8 months ago

Thank you