stacker.news/components/wallet-logs.js

78 lines
2.1 KiB
JavaScript

import { useRouter } from 'next/router'
import LogMessage from './log-message'
import { useWalletLogs } from './logger'
import { useEffect, useRef, useState } from 'react'
import { Checkbox, Form } from './form'
import { useField } from 'formik'
import styles from '@/styles/log.module.css'
const FollowCheckbox = ({ value, ...props }) => {
const [,, helpers] = useField(props.name)
useEffect(() => {
helpers.setValue(value)
}, [value])
return (
<Checkbox {...props} />
)
}
export default function WalletLogs ({ wallet, embedded }) {
const logs = useWalletLogs(wallet)
const router = useRouter()
const { follow: defaultFollow } = router.query
const [follow, setFollow] = useState(defaultFollow ?? true)
const tableRef = useRef()
const scrollY = useRef()
useEffect(() => {
if (follow) {
tableRef.current?.scroll({ top: tableRef.current.scrollHeight, behavior: 'smooth' })
}
}, [logs, follow])
useEffect(() => {
function onScroll (e) {
const y = e.target.scrollTop
const down = y - scrollY.current >= -1
if (!!scrollY.current && !down) {
setFollow(false)
}
const maxY = e.target.scrollHeight - e.target.clientHeight
const dY = maxY - y
const isBottom = dY >= -1 && dY <= 1
if (isBottom) {
setFollow(true)
}
scrollY.current = y
}
tableRef.current?.addEventListener('scroll', onScroll)
return () => tableRef.current?.removeEventListener('scroll', onScroll)
}, [])
return (
<>
<Form initial={{ follow: true }}>
<FollowCheckbox
label='follow logs' name='follow' value={follow}
handleChange={setFollow}
/>
</Form>
<div ref={tableRef} className={`${styles.logTable} ${embedded ? styles.embedded : ''}`}>
<div className='w-100 text-center'>------ start of logs ------</div>
{logs.length === 0 && <div className='w-100 text-center'>empty</div>}
<table>
<tbody>
{logs.map((log, i) => <LogMessage key={i} {...log} />)}
</tbody>
</table>
</div>
</>
)
}