Skip to content

Commit

Permalink
feat: improve scroll syncing (#21622)
Browse files Browse the repository at this point in the history
  • Loading branch information
daibhin authored Apr 22, 2024
1 parent e4c5828 commit 59e0196
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 52 deletions.
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { IconBug, IconClock, IconDashboard, IconInfo, IconPause, IconTerminal, IconX } from '@posthog/icons'
import { IconBug, IconClock, IconDashboard, IconInfo, IconTerminal, IconX } from '@posthog/icons'
import { LemonButton, LemonCheckbox, LemonInput, LemonSelect, LemonTabs, Tooltip } from '@posthog/lemon-ui'
import { useActions, useValues } from 'kea'
import { FEATURE_FLAGS } from 'lib/constants'
import { IconPlayCircle, IconUnverifiedEvent } from 'lib/lemon-ui/icons'
import { IconUnverifiedEvent } from 'lib/lemon-ui/icons'
import { Spinner } from 'lib/lemon-ui/Spinner/Spinner'
import { featureFlagLogic } from 'lib/logic/featureFlagLogic'
import { capitalizeFirstLetter } from 'lib/utils'
Expand Down Expand Up @@ -69,11 +69,10 @@ function TabButtons({
export function PlayerInspectorControls({ onClose }: { onClose: () => void }): JSX.Element {
const { logicProps } = useValues(sessionRecordingPlayerLogic)
const inspectorLogic = playerInspectorLogic(logicProps)
const { tab, windowIdFilter, syncScrollingPaused, windowIds, showMatchingEventsFilter } = useValues(inspectorLogic)
const { setWindowIdFilter, setSyncScrollPaused, setTab } = useActions(inspectorLogic)
const { showOnlyMatching, timestampMode, miniFilters, syncScroll, searchQuery } = useValues(playerSettingsLogic)
const { setShowOnlyMatching, setTimestampMode, setMiniFilter, setSyncScroll, setSearchQuery } =
useActions(playerSettingsLogic)
const { tab, windowIdFilter, windowIds, showMatchingEventsFilter } = useValues(inspectorLogic)
const { setWindowIdFilter, setTab } = useActions(inspectorLogic)
const { showOnlyMatching, timestampMode, miniFilters, searchQuery } = useValues(playerSettingsLogic)
const { setShowOnlyMatching, setTimestampMode, setMiniFilter, setSearchQuery } = useActions(playerSettingsLogic)

const mode = logicProps.mode ?? SessionRecordingPlayerMode.Standard

Expand Down Expand Up @@ -199,34 +198,6 @@ export function PlayerInspectorControls({ onClose }: { onClose: () => void }): J
<IconClock className="text-lg" />
</span>
</LemonButton>

<LemonButton
size="small"
type="secondary"
noPadding
active={syncScroll}
onClick={() => {
// If the user has syncScrolling on, but it is paused due to interacting with the Inspector, we want to resume it
if (syncScroll && syncScrollingPaused) {
setSyncScrollPaused(false)
} else {
// Otherwise we are just toggling the setting
setSyncScroll(!syncScroll)
}
}}
tooltipPlacement="left"
tooltip={
syncScroll && syncScrollingPaused
? 'Synced scrolling is paused - click to resume'
: 'Scroll the list in sync with the recording playback'
}
>
{syncScroll && syncScrollingPaused ? (
<IconPause className="text-lg m-1" />
) : (
<IconPlayCircle className="text-lg m-1" />
)}
</LemonButton>
</div>
</div>
{showMatchingEventsFilter ? (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import { userLogic } from 'scenes/userLogic'
import { sidePanelSettingsLogic } from '~/layout/navigation-3000/sidepanel/panels/sidePanelSettingsLogic'
import { AvailableFeature, SessionRecordingPlayerTab } from '~/types'

import { playerSettingsLogic } from '../playerSettingsLogic'
import { sessionRecordingPlayerLogic } from '../sessionRecordingPlayerLogic'
import { PlayerInspectorListItem } from './components/PlayerInspectorListItem'
import { playerInspectorLogic } from './playerInspectorLogic'
Expand Down Expand Up @@ -114,10 +113,9 @@ export function PlayerInspectorList(): JSX.Element {
const { logicProps, snapshotsLoaded, sessionPlayerMetaData } = useValues(sessionRecordingPlayerLogic)
const inspectorLogic = playerInspectorLogic(logicProps)

const { items, tabsState, playbackIndicatorIndex, playbackIndicatorIndexStop, syncScrollingPaused, tab } =
const { items, tabsState, playbackIndicatorIndex, playbackIndicatorIndexStop, syncScrollPaused, tab } =
useValues(inspectorLogic)
const { setSyncScrollPaused } = useActions(inspectorLogic)
const { syncScroll } = useValues(playerSettingsLogic)
const { currentTeam } = useValues(teamLogic)
const { hasAvailableFeature } = useValues(userLogic)
const performanceAvailable: boolean = hasAvailableFeature(AvailableFeature.RECORDINGS_PERFORMANCE)
Expand Down Expand Up @@ -161,12 +159,12 @@ export function PlayerInspectorList(): JSX.Element {
.getElementById('PlayerInspectorListMarker')
?.setAttribute('style', `transform: translateY(${offset}px)`)

if (!syncScrollingPaused && syncScroll) {
if (!syncScrollPaused) {
scrolledByJsFlag.current = true
listRef.current.scrollToRow(playbackIndicatorIndex)
}
}
}, [playbackIndicatorIndex, syncScroll])
}, [playbackIndicatorIndex])

const renderRow: ListRowRenderer = ({ index, key, parent, style }) => {
return (
Expand Down Expand Up @@ -226,6 +224,22 @@ export function PlayerInspectorList(): JSX.Element {
/>
)}
</AutoSizer>
{syncScrollPaused && (
<div className="absolute bottom-2 left-1/2 translate-x-[-50%] bg-side">
<LemonButton
type="secondary"
onClick={() => {
if (listRef.current) {
listRef.current.scrollToRow(playbackIndicatorIndex)
}
// Tricky: Need to dely to make sure the row scrolled has finished
setTimeout(() => setSyncScrollPaused(false), 100)
}}
>
Sync scrolling
</LemonButton>
</div>
)}
</div>
) : tabsState[tab] === 'loading' ? (
<div className="p-2">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ export const playerInspectorLogic = kea<playerInspectorLogicType>([
connect((props: PlayerInspectorLogicProps) => ({
actions: [
playerSettingsLogic,
['setTab', 'setMiniFilter', 'setSyncScroll', 'setSearchQuery'],
['setTab', 'setMiniFilter', 'setSearchQuery'],
eventUsageLogic,
['reportRecordingInspectorItemExpanded'],
sessionRecordingDataLogic(props),
Expand Down Expand Up @@ -210,13 +210,12 @@ export const playerInspectorLogic = kea<playerInspectorLogicType>([
},
],

syncScrollingPaused: [
syncScrollPaused: [
false,
{
setTab: () => false,
setSyncScrollPaused: (_, { paused }) => paused,
setItemExpanded: () => true,
setSyncScroll: () => false,
},
],
})),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,6 @@ export const playerSettingsLogic = kea<playerSettingsLogicType>([
setTimestampMode: (mode: 'absolute' | 'relative') => ({ mode }),
setMiniFilter: (key: string, enabled: boolean) => ({ key, enabled }),
setSearchQuery: (search: string) => ({ search }),
setSyncScroll: (enabled: boolean) => ({ enabled }),
setDurationTypeToShow: (type: DurationType) => ({ type }),
setShowFilters: (showFilters: boolean) => ({ showFilters }),
setPrefersAdvancedFilters: (prefersAdvancedFilters: boolean) => ({ prefersAdvancedFilters }),
Expand Down Expand Up @@ -347,14 +346,6 @@ export const playerSettingsLogic = kea<playerSettingsLogicType>([
setSearchQuery: (_, { search }) => search || '',
},
],

syncScroll: [
true,
{ persist: true },
{
setSyncScroll: (_, { enabled }) => enabled,
},
],
})),

selectors({
Expand Down

0 comments on commit 59e0196

Please sign in to comment.