melloware / react-logviewer

React Lazy LogViewer
https://melloware.github.io/react-logviewer/
Mozilla Public License 2.0
59 stars 12 forks source link

Text Mode: Log window rescrolls to top #46

Open jektvik opened 14 hours ago

jektvik commented 14 hours ago

The log scrolls to the bottom on first render. But after pushing additional lines to the log, it resets itself to the first line on subsequent rerenders and there doesn't seem to be any way of forcing him to follow the new lines pushed to the bottom. One thing that fixes it is to remove the ScrollFollow component, but then scrolling becomes jerky,

Here's my code which first loads a payload of logs lines on first render, and then pushes additional lines from a websocket channel (however the websocket is handled indepentently from the built-in logviewer api) .

  useEffect(() => {
    const channel = supabase
      .channel('schema-db-changes')
      .on<LogValues>(
        'postgres_changes',
        {
          event: 'INSERT',
          schema: 'public'
        },
        (payload) => logs && setLogs([...logs, payload.new])
      )
      .subscribe()

    return () => {
      ;(async function subscribeToChanges() {
        await supabase.removeChannel(channel)
      })()
    }
  }, [logs])

  useEffect(() => {
    ;(async function getLogs() {
      const { data: respLogs } = await supabase
        .from('application_logs')
        .select()
        .order('created', { ascending: false }) // Sort by 'created' in descending order
        .limit(1000)

      if (respLogs?.length) {
        setLogs(respLogs.reverse())
      }
    })()
  }, [])

  return (
    <Card height={'100%'}>
      <div style={{ height: 500 }}>
        <ScrollFollow
          startFollowing={true}
          render={({ follow, onScroll }) => (
            <LazyLog
              // stream
              // follow={follow}
              scrollToLine={9999}
              onScroll={onScroll}
              caseInsensitive
              enableHotKeys
              enableSearch
              extraLines={1}
              height="520"
              onLineContentClick={function noRefCheck() {}}
              selectableLines
              text={logs
                ?.map(
                  (c) =>
                    // @ts-expect-error just being lazy for typing
                    `${new Date(c.created).toLocaleString('en-GB')}   ${c
                      .values?.['Message']}`
                )
                .join('\n')}
            />
          )}
        />
      </div>
    </Card>
melloware commented 12 hours ago

Yeah this was reported before: https://github.com/melloware/react-logviewer/issues/25 Any help debugging would be great

jektvik commented 11 hours ago

Pass, howver an eventual workaround that worked was to force rerender they entire component every time new data arrives. I use the key method for it:

useEffect(
 ...yourDataFetchingLogic
forceRerender()
...
,[yourDep])
...
  const [key, setKey] = useState(0)
  const forceRerender = () => {
    setKey((prevKey) => prevKey + 1) // Increment key to force re-render
  }
...
<MyTerminal key={key} logs={logs} />