0

I'm developing a chat with the messages virtualized. It works well as a normal list.

Now I'm trying to "style" the messages to go from bottom up (like Whatsapp, Telegram and every message app works).

I have included a display: flex, a flex-direction: column, a justify-content: flex-end on the parent, shown on code down below.

Edit: I have also included a display: flex, a flex-direction: column-reverse on the messages, so they already are in the right order. The problem is their position in the chat, related to the input on the bottom.

I've also put a div between parents with flexbox and AutoSizer because it's required on React-virtualized docs.

<div style={{ position: 'relative', minHeight: '100%', display: 'flex', justifyContent: 'flex-end', flexDirection: 'column' }} >
            <div style={{ flex: '1 1 auto' }}>
                <AutoSizer onResize={scrollToBottom}>
                    {({ width, height }) => (
                        <List
                            ref={ListRef}
                            deferredMeasurementCache={_cache.current}
                            width={width}
                            height={height}
                            overscanRowCount={props.overscanRowCount}
                            noRowsRenderer={_noRowsRenderer}
                            rowCount={xRowCount}
                            rowHeight={_cache.current.rowHeight}
                            rowRenderer={_rowRenderer}
                            scrollToIndex={xRowCount}
                        />
                    )}
                </AutoSizer>
            </div>
        </div>

As described in React-virtualized docs:

One word of caution about using AutoSizer with flexbox containers. Flex containers don't prevent their children from growing and AutoSizer greedily grows to fill as much space as possible. Combining the two can cause a loop. The simple way to fix this is to nest AutoSizer inside of a block element (like a ) rather than putting it as a direct child of the flex container.

The problem is: the flex-end style is not being applied. The list is working as it was before, from top to bottom.

Is there any other way I can do that? If so, I'm open to do it. If this is the way, does anyone know what the problem is?

Edit: I have created a demo for this problem: https://codesandbox.io/s/flexendreactvirtualize-hospg

W. Lucas
  • 23
  • 1
  • 6
  • man just use the sort) – Roman Epifanov Jul 19 '21 at 19:20
  • It's not about the order, it's about the position of the messages on page. They are already in the right order. – W. Lucas Jul 19 '21 at 19:41
  • but what is the problem? just use order by date, and show the latest in the end of div – Roman Epifanov Jul 19 '21 at 19:43
  • if it is css problem just use justify-content: flex-end; https://jsfiddle.net/34yrpfkj/ – Roman Epifanov Jul 19 '21 at 19:49
  • Yes, that's what I'm using. The problem is that I'm using react-virtualized that calculates the height of the element "on demand". So the justify-content: flex-end is not working and I don't know why. – W. Lucas Jul 19 '21 at 19:53
  • it seems to me, it is problem in height, but with out demo it is difficult to find and fix it – Roman Epifanov Jul 19 '21 at 20:11
  • I've created a demo https://codesandbox.io/s/flexendreactvirtualize-hospg @RomanEpifanov – W. Lucas Jul 19 '21 at 23:25
  • Check this, is it what do you need? https://codesandbox.io/s/flexendreactvirtualize-forked-pgwez?file=/src/ListVirtualized.jsx – Roman Epifanov Jul 20 '21 at 08:59
  • Not really, because when there are few messages (not enough to fill the entire chat) they still are on the top of the chat. I would like them to stay on the bottom of the chat, close to the pink line, that represents the input text. – W. Lucas Jul 20 '21 at 11:55
  • I think easy way, create one component with scroll (if you have more than ~5 message) and second one for the empty chat( with basic css) – Roman Epifanov Jul 26 '21 at 08:23

1 Answers1

0

React virtualized positions items absolutely, with style passed in rowRenderer parameters. Overriding this with css is not advised.

Suggestion, instead of trying to solve order with css (override the provided style object if you need to change styles), here is what I suggest:

Use the index prop of rowRenderer to display the right item.

Example:

const _rowRenderer = (index, ...delegate) => {
   // instead of `myItems[index]` to invert order
   const item = myItems[myItems.length - 1 - index]
   return <ItemDisplay item={item} {...delegate} />
}

Something like that?

Pandaiolo
  • 11,165
  • 5
  • 38
  • 70
  • No, because the messages are already in the right order. The most recent is on the bottom, the oldest on the top. I just want to "attach" them to the input where you type the messages. Regular CSS is not working because of react-virtualized. – W. Lucas Jul 19 '21 at 22:27
  • I've created a demo @Pandaiolo https://codesandbox.io/s/flexendreactvirtualize-hospg – W. Lucas Jul 19 '21 at 23:26
  • Right... this is a different problem, not sure how to deal with it, maybe two things in an effect at list mount/new message: 1. if height of virtual grid is smaller than container, add styles to align to bottom 2. otherwise, something like `listRef.scrollTo(0, listRef.scrollHeight)` so that it goes to the bottom? (you would need to keep track of manual user scroll to suspend auto scrolling in that case) – Pandaiolo Jul 22 '21 at 11:23