LiveButton.tsx 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. import type { FetchPreviousPageOptions } from '@tanstack/react-query'
  2. import { CirclePause, CirclePlay } from 'lucide-react'
  3. import { useQueryStates } from 'nuqs'
  4. import { useEffect } from 'react'
  5. import { cn } from 'ui'
  6. import { ButtonTooltip } from '../ButtonTooltip'
  7. import { useDataTable } from './providers/DataTableProvider'
  8. import { SHORTCUT_IDS } from '@/state/shortcuts/registry'
  9. import { useShortcut } from '@/state/shortcuts/useShortcut'
  10. const REFRESH_INTERVAL = 10_000
  11. interface LiveButtonProps {
  12. searchParamsParser: any
  13. fetchPreviousPage?: (options?: FetchPreviousPageOptions | undefined) => Promise<unknown>
  14. }
  15. export function LiveButton({ fetchPreviousPage, searchParamsParser }: LiveButtonProps) {
  16. const [{ live, date, sort }, setSearch] = useQueryStates(searchParamsParser)
  17. const { table } = useDataTable()
  18. useShortcut(SHORTCUT_IDS.DATA_TABLE_TOGGLE_LIVE, handleClick)
  19. useEffect(() => {
  20. let timeoutId: NodeJS.Timeout
  21. async function fetchData() {
  22. if (live) {
  23. await fetchPreviousPage?.()
  24. timeoutId = setTimeout(fetchData, REFRESH_INTERVAL)
  25. } else {
  26. clearTimeout(timeoutId)
  27. }
  28. }
  29. fetchData()
  30. return () => {
  31. clearTimeout(timeoutId)
  32. }
  33. }, [live, fetchPreviousPage])
  34. // REMINDER: make sure to reset live when date is set
  35. // TODO: test properly
  36. useEffect(() => {
  37. if ((date || sort) && live) {
  38. setSearch((prev) => ({ ...prev, live: null }))
  39. }
  40. }, [date, sort])
  41. function handleClick() {
  42. setSearch((prev) => ({
  43. ...prev,
  44. live: !prev.live,
  45. date: null,
  46. sort: null,
  47. }))
  48. table.getColumn('date')?.setFilterValue(undefined)
  49. table.resetSorting()
  50. }
  51. return (
  52. <ButtonTooltip
  53. className={cn(live && 'border-info text-info hover:text-info')}
  54. onClick={handleClick}
  55. type={live ? 'primary' : 'default'}
  56. size="tiny"
  57. icon={live ? <CirclePause className="h-4 w-4" /> : <CirclePlay className="h-4 w-4" />}
  58. tooltip={{ content: { side: 'bottom', text: live ? 'Pause live mode' : 'Start live mode' } }}
  59. >
  60. Live
  61. </ButtonTooltip>
  62. )
  63. }