openreplay/frontend/app/components/Spots/SpotPlayer/components/SpotActivity.tsx
Andrey Babushkin fd5c0c9747
Add lokalisation (#3092)
* applied eslint

* add locales and lint the project

* removed error boundary

* updated locales

* fix min files

* fix locales
2025-03-06 17:43:15 +01:00

118 lines
3.2 KiB
TypeScript

import { CloseOutlined } from '@ant-design/icons';
import { TYPES } from 'Types/session/event';
import { Button } from 'antd';
import { observer } from 'mobx-react-lite';
import React from 'react';
import Event from 'Components/Session_/EventsBlock/Event';
import spotPlayerStore from '../spotPlayerStore';
import { useTranslation } from 'react-i18next';
function SpotActivity({ onClose }: { onClose: () => void }) {
const { t } = useTranslation();
const mixedEvents = React.useMemo(() => {
const result = [...spotPlayerStore.locations, ...spotPlayerStore.clicks];
return result.sort((a, b) => a.time - b.time);
}, [spotPlayerStore.locations, spotPlayerStore.clicks]);
const { index } = spotPlayerStore.getHighlightedEvent(
spotPlayerStore.time,
mixedEvents,
);
const jump = (time: number) => {
spotPlayerStore.setTime(time / 1000);
};
const getShadowColor = (ind: number) => {
if (ind < index) return '#A7BFFF';
if (ind === index) return '#394EFF';
return 'transparent';
};
return (
<div
className="h-full bg-white border-l"
style={{ minWidth: 320, width: 320 }}
>
<div className="flex items-center justify-between p-4">
<div className="font-medium text-lg">{t('Activity')}</div>
<Button type="text" size="small" onClick={onClose}>
<CloseOutlined />
</Button>
</div>
<div
className="overflow-y-auto"
style={{ maxHeight: 'calc(100vh - 128px)' }}
>
{mixedEvents.map((event, i) => (
<div
key={event.time}
onClick={() => jump(event.time)}
className="relative"
>
<div
style={{
position: 'absolute',
left: 0,
top: 0,
width: 1.5,
height: '100%',
backgroundColor: getShadowColor(i),
zIndex: 98,
}}
/>
{i === index ? (
<div
style={{
position: 'absolute',
top: '50%',
left: -10,
width: 10,
height: 10,
transform: 'rotate(45deg) translate(0, -50%)',
background: '#394EFF',
zIndex: 99,
borderRadius: '.15rem',
}}
/>
) : null}
{'label' in event ? (
// @ts-ignore
<ClickEv event={event} isCurrent={i === index} />
) : (
<LocationEv event={event} isCurrent={i === index} />
)}
</div>
))}
</div>
</div>
);
}
function LocationEv({
event,
isCurrent,
}: {
event: { time: number; location: string };
isCurrent?: boolean;
}) {
const locEvent = { ...event, type: TYPES.LOCATION, url: event.location };
return <Event showLoadInfo whiteBg event={locEvent} isCurrent={isCurrent} />;
}
function ClickEv({
event,
isCurrent,
}: {
event: { time: number; label: string };
isCurrent?: boolean;
}) {
const clickEvent = {
type: TYPES.CLICK,
label: event.label,
count: 1,
};
return <Event whiteBg event={clickEvent} isCurrent={isCurrent} />;
}
export default observer(SpotActivity);