122 lines
3.6 KiB
JavaScript
122 lines
3.6 KiB
JavaScript
import { useRouter } from 'next/router'
|
|
import LogMessage from './log-message'
|
|
import { useWalletLogger, 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'
|
|
import { Button } from 'react-bootstrap'
|
|
import { useToast } from './toast'
|
|
import { useShowModal } from './modal'
|
|
|
|
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()
|
|
const showModal = useShowModal()
|
|
|
|
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 (
|
|
<>
|
|
<div className='d-flex w-100 align-items-center mb-3'>
|
|
<Form initial={{ follow: true }}>
|
|
<FollowCheckbox
|
|
label='follow logs' name='follow' value={follow}
|
|
handleChange={setFollow} groupClassName='mb-0'
|
|
/>
|
|
</Form>
|
|
<span
|
|
style={{ cursor: 'pointer' }}
|
|
className='text-muted fw-bold nav-link' onClick={() => {
|
|
showModal(onClose => <DeleteWalletLogsObstacle wallet={wallet} onClose={onClose} />)
|
|
}}
|
|
>clear
|
|
</span>
|
|
</div>
|
|
<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>
|
|
</>
|
|
)
|
|
}
|
|
|
|
function DeleteWalletLogsObstacle ({ wallet, onClose }) {
|
|
const toaster = useToast()
|
|
const { deleteLogs } = useWalletLogger(wallet)
|
|
|
|
const prompt = `Do you really want to delete all ${wallet ? '' : 'wallet'} logs ${wallet ? 'of this wallet' : ''}?`
|
|
return (
|
|
<div className='text-center'>
|
|
{prompt}
|
|
<div className='d-flex justify-center align-items-center mt-3 mx-auto'>
|
|
<span style={{ cursor: 'pointer' }} className='d-flex ms-auto text-muted fw-bold nav-link mx-3' onClick={onClose}>cancel</span>
|
|
<Button
|
|
className='d-flex me-auto mx-3' variant='danger'
|
|
onClick={
|
|
async () => {
|
|
try {
|
|
await deleteLogs()
|
|
onClose()
|
|
toaster.success('deleted wallet logs')
|
|
} catch (err) {
|
|
console.error(err)
|
|
toaster.danger('failed to delete wallet logs')
|
|
}
|
|
}
|
|
}
|
|
>delete
|
|
</Button>
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|