Hangouts-like Chat Design

I created a chat design that looks similar to Google Hangouts chat, with messages in speech bubbles, inside a card that scrolls to the bottom automatically.

https://anvil.works/build#clone:X3NLEWNXN7EKTRVA=Z25OY6KF7Q26MPLO4BOUCJJS

I guess the innovations are the CSS that creates the speech bubbles (probably considered pretty basic but it was a stretch for me), and the repeating panel template that displays a different format depending on whether the message is from me or the other person. Oh, also applying auto-scrolling to a card, as opposed to a text area. It uses custom roles, defined in lines 103-168 of theme.css. (The auto-scrolling requires one JS script based on @shaun’s code linked above, inserted into the standard.html file).

Note: This is just a design, not a functioning chat app. It doesn’t incorporate the Users service, so all messages sent are labeled as “me.” Messages from the other person can only be entered in manually to the Data Tables via the IDE.

18 Likes

This is incredibly impressive. I’ll be “borrowing” some of this code for sure. Really nice job, thank you for sharing!

2 Likes

great example, thanks for sharing. will def be using this.

2 Likes

thank you, great example. Do you have any idea how to check in real time if the message is from ‘me’ in multiuser app ? Now you are taking the info from datatables, but with more users there has to be different way, but I can not figure it out :slight_smile:

2 Likes

Sure, in the multi-user app, I have a “user” field in the Messages table which links to the Users table. In my use case, I don’t want to reveal the identity of the other person, so I have a server function that just returns whether a message is me:

@anvil.server.callable
def get_messages(user_id=""):
  """
  Returns iterable of dictionaries with keys: 'me', 'message'
  """
  user_id = anvil.users.get_user().get_id()
  user = app_tables.users.get_by_id(user_id)
  current_match = _current_match(user)
  messages = app_tables.chat.search(match=current_match)
  if messages:
    return [{'me': (user == m['user']), 'message': m['message']} for m in messages]

Does that make sense? If it’s helpful, I can fill in more of the other details, or you can look at part 1 of this example: https://anvil.works/learn/examples/magic

3 Likes

I love it, thanks for sharing!

2 Likes

I am not focusing on design right now but rather on making it functional. So I just created a table called Chat having a ‘USER’ column and the rest of the columns will be added automatically and have name of users. So suppose a guy called x want to message a person called y. Then, a row will be added having ‘USER’ as x and in y column there will be a nested list having all the messages and ‘r’ or ‘s’ as per sent or received.

Then I ran a loop in self liner panel in such a way that if if the value at index of 1 is r, it will be aligned left else right.

Tell me if anyone wants a clone.

2 Likes

please post a clone, will be eager to check it out

https://anvil.works/build#clone:BV5HCYPIM3XMOVVA=4QPEFB6MWOSPLVA3XIVZFDKS
@ananth.krishnamoorth
Here you go. Publish this app and open the app url in two different tabs. Then make sure that the sender from one tab is the receiver from the other. That way, you can chat with yourself. You’ll notice that new messages appear instantly.

Also, if auto-create columns isn’t enabled, please enable it from data tables.

1 Like

Thanks. Works well, thanks for sharing

You’re welcome :grinning:

Do tell me if you need any more help