Skip to content

Commit

Permalink
fix: artifically delay rendering of reference counts to reduce overfe…
Browse files Browse the repository at this point in the history
…tching on scroll
  • Loading branch information
robinpyon committed Jul 5, 2023
1 parent 1605a00 commit 2d422d9
Showing 1 changed file with 67 additions and 45 deletions.
112 changes: 67 additions & 45 deletions src/components/TableRowAsset/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {hues} from '@sanity/color'
import {CheckmarkCircleIcon, EditIcon, WarningFilledIcon, SpinnerIcon} from '@sanity/icons'
import {CheckmarkCircleIcon, EditIcon, WarningFilledIcon} from '@sanity/icons'
import {
Box,
Checkbox,
Expand All @@ -13,7 +13,7 @@ import {
} from '@sanity/ui'
import formatRelative from 'date-fns/formatRelative'
import filesize from 'filesize'
import React, {memo, MouseEvent, RefObject} from 'react'
import React, {memo, MouseEvent, RefObject, useCallback, useEffect, useRef, useState} from 'react'
import {useDispatch} from 'react-redux'
import styled, {css} from 'styled-components'
import {GRID_TEMPLATE_COLUMNS} from '../../constants'
Expand All @@ -29,6 +29,9 @@ import FileIcon from '../FileIcon'
import Image from '../Image'
import {WithReferringDocuments} from 'sanity'

// Duration (ms) to wait before reference counts (and associated listeners) are rendered
const REFERENCE_COUNT_VISIBILITY_DELAY = 750

type Props = {
id: string
selected: boolean
Expand Down Expand Up @@ -69,13 +72,15 @@ const StyledWarningIcon = styled(WarningFilledIcon)(({theme}) => {
}
})

// eslint-disable-next-line complexity
const TableRowAsset = (props: Props) => {
const {id, selected} = props

// Refs
const shiftPressed: RefObject<boolean> = useKeyPress('shift')

// Redux
const [referenceCountVisible, setReferenceCountVisible] = useState(false)
const refCountVisibleTimeout = useRef<ReturnType<typeof window.setTimeout>>()

const dispatch = useDispatch()
const lastPicked = useTypedSelector(state => state.assets.lastPicked)
const item = useTypedSelector(state => selectAssetById(state, id))
Expand All @@ -90,48 +95,61 @@ const TableRowAsset = (props: Props) => {

const {onSelect} = useAssetSourceActions()

// Short circuit if no asset is available
if (!asset) {
return null
}

// Callbacks
const handleContextActionClick = (e: MouseEvent<HTMLDivElement>) => {
e.stopPropagation()
const handleContextActionClick = useCallback(
(e: MouseEvent<HTMLDivElement>) => {
e.stopPropagation()

if (onSelect) {
dispatch(dialogActions.showAssetEdit({assetId: asset._id}))
} else if (shiftPressed.current && !picked) {
dispatch(assetsActions.pickRange({startId: lastPicked || asset._id, endId: asset._id}))
} else {
dispatch(assetsActions.pick({assetId: asset._id, picked: !picked}))
}
}
if (onSelect) {
dispatch(dialogActions.showAssetEdit({assetId: asset._id}))
} else if (shiftPressed.current && !picked) {
dispatch(assetsActions.pickRange({startId: lastPicked || asset._id, endId: asset._id}))
} else {
dispatch(assetsActions.pick({assetId: asset._id, picked: !picked}))
}
},
[asset._id, dispatch, lastPicked, onSelect, picked, shiftPressed]
)

const handleClick = (e: MouseEvent<HTMLDivElement>) => {
e.stopPropagation()
const handleClick = useCallback(
(e: MouseEvent<HTMLDivElement>) => {
e.stopPropagation()

if (onSelect) {
onSelect([
{
kind: 'assetDocumentId',
value: asset._id
if (onSelect) {
onSelect([{kind: 'assetDocumentId', value: asset._id}])
} else if (shiftPressed.current) {
if (picked) {
dispatch(assetsActions.pick({assetId: asset._id, picked: !picked}))
} else {
dispatch(assetsActions.pickRange({startId: lastPicked || asset._id, endId: asset._id}))
}
])
} else if (shiftPressed.current) {
if (picked) {
dispatch(assetsActions.pick({assetId: asset._id, picked: !picked}))
} else {
dispatch(assetsActions.pickRange({startId: lastPicked || asset._id, endId: asset._id}))
dispatch(dialogActions.showAssetEdit({assetId: asset._id}))
}
} else {
dispatch(dialogActions.showAssetEdit({assetId: asset._id}))
}
}
},
[asset._id, dispatch, lastPicked, onSelect, picked, shiftPressed]
)

const opacityCell = updating ? 0.5 : 1
const opacityPreview = selected || updating ? 0.1 : 1

// Display reference count after an initial delay to prevent over-eager fetching
useEffect(() => {
refCountVisibleTimeout.current = setTimeout(
() => setReferenceCountVisible(true),
REFERENCE_COUNT_VISIBILITY_DELAY
)
return () => {
if (refCountVisibleTimeout.current) {
clearTimeout(refCountVisibleTimeout.current)
}
}
}, [])

// Short circuit if no asset is available
if (!asset) {
return null
}

return (
<ContainerGrid
onClick={selected ? undefined : handleClick}
Expand Down Expand Up @@ -321,15 +339,19 @@ const TableRowAsset = (props: Props) => {
}}
>
<Text muted size={1} style={{lineHeight: '2em'}} textOverflow="ellipsis">
<WithReferringDocuments id={id}>
{({isLoading, referringDocuments}) =>
isLoading ? (
<SpinnerIcon />
) : (
<>{Array.isArray(referringDocuments) ? referringDocuments.length : 0}</>
)
}
</WithReferringDocuments>
{referenceCountVisible ? (
<WithReferringDocuments id={id}>
{({isLoading, referringDocuments}) =>
isLoading ? (
<>-</>
) : (
<>{Array.isArray(referringDocuments) ? referringDocuments.length : 0}</>
)
}
</WithReferringDocuments>
) : (
<>-</>
)}
</Text>
</Box>

Expand Down

0 comments on commit 2d422d9

Please sign in to comment.