openreplay/frontend/app/components/Spots/SpotPlayer/components/SpotPlayerHeader.tsx
Delirium b17c3ab8d7
Spots UI (#2385)
* feat ui: login flow for spot extension

* spot list, store and service created

* some fixing for header

* start work on single spot

* spot player start

* header for player, comments, icons, etc

* split stuff into compoennts, create player state manager

* player controls, activity panel etc etc

* comments, empty page, rename and stuff

* interval buttons etc

* access modal

* pubkey support

* fix tooltip

* limit 10 -> 9

* hls lib instead of videojs

* some warnings

* fix date display for exp

* change public links

* display more client data

* fix cleaning, init comment

* map network to replay player network ev

* stream support, console panel, close panels on X

* fixing streaming, destroy on leave

* fix autoplay

* show notification on spot login

* fix spot login

* backup player added, fix audio issue

* show thumbnail when no video, add spot roles

* add poster thumbnail

* some fixes to video check

* fix events jump

* fix play btn

* try catch over pubkey

* icons

* spot login pinging

* move spot login flow to login comp, use separate spot login path for unique jwt

* invalidate spot jwt on logout

* add visual data on page load event

* typo fix

* issue to copy change

* share spot url f
2024-07-31 09:56:41 +02:00

166 lines
4.4 KiB
TypeScript

import {
ArrowLeftOutlined,
CommentOutlined,
LinkOutlined,
SettingOutlined,
UserSwitchOutlined,
} from '@ant-design/icons';
import { Button, Popover } from 'antd';
import copy from 'copy-to-clipboard';
import React from 'react';
import { connect } from 'react-redux';
import { Link } from 'react-router-dom';
import { spotsList } from 'App/routes';
import { hashString } from 'App/types/session/session';
import { Avatar, Icon } from 'UI';
import { TABS, Tab } from '../consts';
import AccessModal from './AccessModal';
const spotLink = spotsList();
function SpotPlayerHeader({
activeTab,
setActiveTab,
title,
user,
date,
isLoggedIn,
browserVersion,
resolution,
platform,
hasShareAccess,
}: {
activeTab: Tab | null;
setActiveTab: (tab: Tab) => void;
title: string;
user: string;
date: string;
isLoggedIn: boolean;
browserVersion: string | null;
resolution: string | null;
platform: string | null;
hasShareAccess: boolean;
}) {
const [isCopied, setIsCopied] = React.useState(false);
const [dropdownOpen, setDropdownOpen] = React.useState(false);
const onCopy = () => {
setIsCopied(true);
copy(window.location.href);
setTimeout(() => setIsCopied(false), 2000);
};
return (
<div
className={
'flex items-center gap-4 p-4 w-full bg-white border-b border-gray-light'
}
>
<div>
{isLoggedIn ? (
<Link to={spotLink}>
<div className={'flex items-center gap-2'}>
<ArrowLeftOutlined />
<div className={'font-semibold'}>All Spots</div>
</div>
</Link>
) : (
<>
<div className={'flex items-center gap-2'}>
<Icon name={'orSpot'} size={24} />
<div className={'text-lg font-semibold'}>Spot</div>
</div>
<div className={'text-disabled-text text-xs'}>by OpenReplay</div>
</>
)}
</div>
<div
className={'h-full rounded-xl bg-gray-light mx-2'}
style={{ width: 1 }}
/>
<div className={'flex items-center gap-2'}>
<Avatar seed={hashString(user)} />
<div>
<div>{title}</div>
<div className={'flex items-center gap-2 text-disabled-text'}>
<div>{user}</div>
<div>·</div>
<div>{date}</div>
{browserVersion && (
<>
<div>·</div>
<div>Chrome v{browserVersion}</div>
</>
)}
{resolution && (
<>
<div>·</div>
<div>{resolution}</div>
</>
)}
{platform && (
<>
<div>·</div>
<div>{platform}</div>
</>
)}
</div>
</div>
</div>
<div className={'ml-auto'} />
{isLoggedIn ? (
<>
<Button
size={'small'}
onClick={onCopy}
type={'primary'}
icon={<LinkOutlined />}
>
{isCopied ? 'Copied!' : 'Copy Link'}
</Button>
{hasShareAccess ? (
<Popover open={dropdownOpen} content={<AccessModal />}>
<Button
size={'small'}
onClick={() => setDropdownOpen(!dropdownOpen)}
icon={<SettingOutlined />}
>
Manage Access
</Button>
</Popover>
) : null}
<div
className={'h-full rounded-xl bg-gray-light mx-2'}
style={{ width: 1 }}
/>
</>
) : null}
<Button
size={'small'}
disabled={activeTab === TABS.ACTIVITY}
onClick={() => setActiveTab(TABS.ACTIVITY)}
icon={<UserSwitchOutlined />}
>
Activity
</Button>
<Button
size={'small'}
disabled={activeTab === TABS.COMMENTS}
onClick={() => setActiveTab(TABS.COMMENTS)}
icon={<CommentOutlined />}
>
Comments
</Button>
</div>
);
}
export default connect((state: any) => {
const jwt = state.getIn(['user', 'jwt']);
const isEE = state.getIn(['user', 'account', 'edition']) === 'ee';
const permissions: string[] =
state.getIn(['user', 'account', 'permissions']) || [];
const hasShareAccess = isEE ? permissions.includes('SPOT_PUBLIC') : true;
return { isLoggedIn: !!jwt, hasShareAccess };
})(SpotPlayerHeader);