Page 1 of 1

Adding a chat system into a project

PostPosted: Thu Mar 07, 2024 5:51 pm
by alasdairs
Hi all,

I wanted to add a chat system into my project and have set up a text file creation for the logs, pushing the messages with username, time and message, and loading the logs from file when the chat is opened. I made a form component for the chat bubble, and the main form has a list formcomponent container on it with the contained form set to the chat bubble form component but I'm not sure where to go from here. Does anyone know how to dynamically add extra chat bubbles to the list form container in runtime?

Here is my current code:

Code: Select all
function loadChat(fileContent) {
    var lines = fileContent.split('\n');
   
    chatLogsArray = [];
   
    for (var i = 0; i < lines.length; i++) {
        var line = lines[i];
        var match = line.match(/^(.*?) (\d{2}:\d{2}:\d{2}) - (.*)$/);
          if (match) {
           var user = match[1];
           var time = match[2];
           var message = match[3];

           chatLogsArray.push({ user: user, time: time, message: message });
        }
    }
    application.output(chatLogsArray);
   populateChatList();
}

function populateChatList() {
   for (var i = 0; i < chatLogsArray.length; i++) {
        var chatEntry = chatLogsArray[i];
       
        var chatComponent = createAndConfigureChatComponent(chatEntry);
       
        addChatComponentToList(chatComponent);
    }
}


I currently don't have a function set up for either the createAndConfigureChatComponent(chatEntry) or the addChatComponentToList(chatComponent).

Thanks!
Alasdair

Re: Adding a chat system into a project

PostPosted: Thu Mar 07, 2024 6:07 pm
by mboegem
Hi Alasdair,

Question: from your previous posts I know you're using NG client, thus browser.
The browser won't be able to read files directly, so how are you seeing this text file to work?
Why not using a database, using a database you can also use the data broadcast event to trigger the chat update

In order to display messages you also might want to have a look at the customrenderer component.
You can just push data into the component and rendering will be done client-side using a render template (which you of course need to provide to the component)

Re: Adding a chat system into a project

PostPosted: Thu Mar 07, 2024 6:32 pm
by alasdairs
Hi Marc,

Currently I'm creating a reading the txt file just using the file plugin, and it seems to be working both in local runtime and when running on a server.
Code: Select all
var chatLog = scopes.global.chatLog()
var previousChatLog = plugins.file.readTXTFile(chatLog)


Thats a good point though, wasn't sure how I was going to get around that. I'll change the solution to use a database.
By customrenderer component do you mean the custom list?

Re: Adding a chat system into a project

PostPosted: Thu Mar 07, 2024 6:37 pm
by mboegem
alasdairs wrote:Currently I'm creating a reading the txt file just using the file plugin, and it seems to be working both in local runtime and when running on a server.

Correct it does, but the file is then read from the server.
Often developer find this 'read file' works perfectly in developer using a browser based client, but don't realise it's actually a serverside process (file plugin = java = server)

alasdairs wrote:By customrenderer component do you mean the custom list?

Yes, awesome component :-)

Re: Adding a chat system into a project

PostPosted: Thu Mar 07, 2024 7:22 pm
by alasdairs
Brilliant, Thanks!

Could the custom lists render template be the 'chat bubble' form component? Not entirely sure where to start with this component.
I need to be able to change the style classes of each of the entries or chat bubbles pushed to the list, depending on who sent them.

Re: Adding a chat system into a project

PostPosted: Fri Mar 08, 2024 10:21 am
by mboegem
Through code you can add entries to the component.
Each entry is an object with the data for that particular entry.
Data can be anything: text you want to show, the type of entry or the style classes

You will also need a render function, which could look like this:
Code: Select all
function onRender(entry) {
var _html += '\
   <div class="list-row">\
      <div class="list-cell-icon"><i class="fa-light fa-calendar-lines"></i></div>\
      <div class="list-cell-container"> \
         <div class="list-text-primary">' + entry.date + '<span class="plan-user">' + entry.user + '</span></div>\
         ' + entry.description + ' \
      </div>\
      <div class="list-cell-chevron ' + entry.class + '"><i class="' + entry.icon + '"></i></div>\
   </div>';

return _html;


The above function can be pasted as text into the dedicated property of the component, or you can do this through code in the onShow of the form, like this:
Code: Select all
function setOnRender(_sFormName, _sFunctionName) {
   var _jsForm = solutionModel.getForm(controller.getName());
   var _sCode = _jsForm.getMethod('onRender').code.replace(/\s\* @properties?[^}]+(}\n|$)/g, '');
   
   return _sCode;
}

function onShow(firstShow, event) {
   elements.list.entryRendererFunction = setOnRender();
}


As you will find, there's also an entryStyleClassFunction property, that will process a function similar to the above, but then just returning the style class(es) as a string.
This can be nice to separate things, but passing in classes as per my example also works fine.

The above should get you started I guess.
One important thing to mention is that the code in the onRender function will completely run browser side.
This means it does not know anything about Servoy, therefore any code should just be plain javascript.
Tip: if you need to display dates, you can already set the formatted string into the entry objects by using a Servoy function.

Another thing: if you are going to use a database you can also use the foundset list.
This works in a similar way, just not an object but mapping of dataproviders.

Hope this helps

Re: Adding a chat system into a project

PostPosted: Fri Mar 08, 2024 1:17 pm
by alasdairs
Thanks a bunch, got it working now! Had a bunch of trouble getting the onRender function working last night.
Ended up putting all the style classes into the onRender function in the end.
Code: Select all
function renderChatEntry(entry) {
    if (entry) {
        var html = '<span class="' + entry.newMessageStyle + '">New Messages</span>' +
                   '<span class="chat-time">' + entry.displayTime + '</span>' +
                   '<span class="chat-user">' + entry.vuser + '</span>' +
                   '<div class="chat-message ' + entry.styleClass + '">' + entry.vmessage + '</div>' +
                   '</div>';
        return html;
    }
}

Thanks for all the help!

Re: Adding a chat system into a project

PostPosted: Fri Mar 08, 2024 2:35 pm
by mboegem
Great, looks good!
I see you got some good fatherly advice there in the chat ;-)

Re: Adding a chat system into a project

PostPosted: Tue Mar 26, 2024 3:11 pm
by bodnarescu.diana
Hi Alasdair,

Are you able to scroll to the bottom of the chat, from code?
I chose aggrid for my chat because I could not do this using the customlist component.

Thanks,
Diana

Re: Adding a chat system into a project

PostPosted: Tue Mar 26, 2024 8:16 pm
by alasdairs
Hi Diana,

I think I got it to load the chat upwards instead of scolling to the bottom.
I recommend using the customlist component if possible, because it feels like it was made for something like this and I can help if you have any questions for it. It's built with dynamic html on load, so you can pass in things like whether the person is you or someone else and the styles for each of them. It's basically like a datagrid made out of your own html.

Here's my code:
Code: Select all
function loadChat() {
   foundset.sort('index asc')
   foundset.loadAllRecords()
   var entryArray = []
   for (var i = 1; i <= foundset.getSize(); i++) {
      var entry = getChatLogEntry(foundset.getRecord(i), i)
      if (entry) {
         entryArray.push(entry);
      }
   }
   elements.chatList.setEntries(entryArray.reverse())
}


CSS:
Code: Select all
.chat-view {
    display: flex;                  // this and
    flex-direction: column-reverse; // this specifically
    overflow-y: auto;
    max-height: 420px;
    padding-bottom: 4px;
    scrollbar-width: none;
    -ms-overflow-style: none;
}


Not sure whether this would work for a datagrid but thats what I did.

Alasdair

Re: Adding a chat system into a project

PostPosted: Wed Mar 27, 2024 11:36 am
by bodnarescu.diana
Hi Alasdair,

Nice trick with the flex-direction: column-reverse :)