develop #222

Merged
andrey.dekterev merged 7 commits from develop into master 3 years ago
  1. 1
      Makefile
  2. 1
      package.json
  3. 54
      src/components/ErrorBoundary/index.tsx
  4. 2
      src/config/clients/lff.tsx
  5. 2
      src/config/lexics/matchDownload.tsx
  6. 2
      src/features/App/index.tsx
  7. 3
      src/features/AuthServiceApp/components/ConfirmPopup/index.tsx
  8. 12
      src/features/GlobalStyles/index.tsx
  9. 2
      src/features/MatchPage/store/hooks/index.tsx
  10. 8
      src/features/MatchPage/store/hooks/usePlayersStats.tsx
  11. 24
      src/features/MatchPage/store/hooks/useStatsTab.tsx
  12. 6
      src/features/MatchPage/store/hooks/useTeamsStats.tsx
  13. 68
      src/features/MatchSidePlaylists/components/TeamsStatsTable/Cell.tsx
  14. 26
      src/features/MatchSidePlaylists/components/TeamsStatsTable/hooks.tsx
  15. 6
      src/features/MatchSidePlaylists/components/TeamsStatsTable/index.tsx
  16. 6
      src/features/MatchSidePlaylists/components/TeamsStatsTable/styled.tsx
  17. 16
      src/features/StreamPlayer/hooks/index.tsx
  18. 28
      src/features/UserAccount/components/PersonalInfoForm/index.tsx
  19. 9
      src/helpers/callApi/logoutIfUnauthorized.tsx
  20. 15
      src/index.tsx

@ -204,4 +204,3 @@ test:
generate-ssl-keys: generate-ssl-keys:
openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 365 openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 365

@ -23,7 +23,6 @@
}, },
"dependencies": { "dependencies": {
"@reactour/tour": "^3.3.0", "@reactour/tour": "^3.3.0",
"@sentry/react": "^7.53.1",
"@stripe/react-stripe-js": "^1.4.0", "@stripe/react-stripe-js": "^1.4.0",
"@stripe/stripe-js": "^1.13.2", "@stripe/stripe-js": "^1.13.2",
"babel-polyfill": "^6.26.0", "babel-polyfill": "^6.26.0",

@ -1,8 +1,8 @@
import React from 'react' // eslint-disable react/destructuring-assignment
import type{ ReactNode } from 'react' import { Component } from 'react'
import * as Sentry from '@sentry/react' import type{ ErrorInfo, ReactNode } from 'react'
import { Error } from '../Error' import { Error } from '../Error'
@ -10,15 +10,41 @@ interface Props {
children?: ReactNode, children?: ReactNode,
} }
export const ErrorBoundary = ({ children }: Props) => ( interface State {
<Sentry.ErrorBoundary fallback={( hasError: boolean,
<> }
{children}
<Error /> class ErrorBoundary extends Component<Props, State> {
</> // eslint-disable-next-line react/state-in-constructor
)} public state: State = {
> hasError: false,
{ children } }
</Sentry.ErrorBoundary>
) public static getDerivedStateFromError(_: Error): State {
// Update state so the next render will show the fallback UI.
return { hasError: true }
}
public componentDidCatch(error: Error, errorInfo: ErrorInfo) {
// eslint-disable-next-line no-console
console.error(
'Uncaught error:',
error,
errorInfo,
)
}
public render() {
const { hasError } = this.state
const { children } = this.props
return (
<>
{hasError && <Error />}
{children}
</>
)
}
}
export default ErrorBoundary

@ -19,7 +19,7 @@ export const lff: ClientConfig = {
disabledHighlights: true, disabledHighlights: true,
disabledPreferences: true, disabledPreferences: true,
name: ClientNames.Lff, name: ClientNames.Lff,
privacyLink: '/clients/instat/terms-and-conditions.html', privacyLink: '/privacy-policy-and-statement',
showSearch: true, showSearch: true,
styles: { styles: {
background: 'background-image: url(/images/Checker.png);', background: 'background-image: url(/images/Checker.png);',

@ -1,7 +1,7 @@
export const matchDownload = { export const matchDownload = {
choose_what_to_download: 20193, choose_what_to_download: 20193,
download_files_for_periods: 20197, download_files_for_periods: 20197,
download_full_match: 9435, download_full_match: 20198,
download_single_file: 20196, download_single_file: 20196,
entire_record: 20195, entire_record: 20195,
in_game_time_only: 20194, in_game_time_only: 20194,

@ -23,7 +23,7 @@ import { GlobalStyles } from 'features/GlobalStyles'
import { Theme } from 'features/Theme' import { Theme } from 'features/Theme'
import { UnavailableText } from 'components/UnavailableText' import { UnavailableText } from 'components/UnavailableText'
import { ErrorBoundary } from 'components/ErrorBoundary' import ErrorBoundary from 'components/ErrorBoundary'
import { AuthenticatedApp } from './AuthenticatedApp' import { AuthenticatedApp } from './AuthenticatedApp'
import { useAuthStore } from '../AuthStore' import { useAuthStore } from '../AuthStore'

@ -1,7 +1,6 @@
import { T9n } from 'features/T9n' import { T9n } from 'features/T9n'
import { client } from 'features/AuthServiceApp/config/clients' import { client } from 'config/clients'
import { AUTH_SERVICE } from 'config/routes' import { AUTH_SERVICE } from 'config/routes'
import { import {

@ -1,6 +1,4 @@
import { createGlobalStyle, css } from 'styled-components/macro' import { createGlobalStyle } from 'styled-components/macro'
import { isMobileDevice } from 'config/userAgent'
export const GlobalStyles = createGlobalStyle` export const GlobalStyles = createGlobalStyle`
*, *:before, *:after { *, *:before, *:after {
@ -9,13 +7,7 @@ export const GlobalStyles = createGlobalStyle`
html { html {
font-size: calc(2px + 1vw); font-size: calc(2px + 1vw);
overflow-y: hidden; overflow-y: auto;
${isMobileDevice
? css`
overflow-y: auto;
`
: ''};
} }
body { body {

@ -296,7 +296,6 @@ export const useMatchPage = () => {
} = useTeamsStats({ } = useTeamsStats({
matchProfile, matchProfile,
playingProgress, playingProgress,
selectedPlaylist,
selectedStatsTable, selectedStatsTable,
selectedTab, selectedTab,
setIsTeamsStatsFetching, setIsTeamsStatsFetching,
@ -311,7 +310,6 @@ export const useMatchPage = () => {
} = usePlayersStats({ } = usePlayersStats({
matchProfile, matchProfile,
playingProgress, playingProgress,
selectedPlaylist,
selectedStatsTable, selectedStatsTable,
selectedTab, selectedTab,
setIsPlayersStatsFetching, setIsPlayersStatsFetching,

@ -36,9 +36,7 @@ import { getLocalStorageItem } from 'helpers/getLocalStorage'
import { useObjectState, usePageParams } from 'hooks' import { useObjectState, usePageParams } from 'hooks'
import type{ PlaylistOption } from 'features/MatchPage/types'
import { StatsType, Tabs as StatsTabs } from 'features/MatchSidePlaylists/components/TabStats/config' import { StatsType, Tabs as StatsTabs } from 'features/MatchSidePlaylists/components/TabStats/config'
import { FULL_GAME_KEY } from 'features/MatchPage/helpers/buildPlaylists'
import { getHalfTime } from 'features/MatchPage/helpers/getHalfTime' import { getHalfTime } from 'features/MatchPage/helpers/getHalfTime'
import { TOUR_COMPLETED_STORAGE_KEY } from 'features/MatchTour' import { TOUR_COMPLETED_STORAGE_KEY } from 'features/MatchTour'
import { Tabs } from 'features/MatchSidePlaylists/config' import { Tabs } from 'features/MatchSidePlaylists/config'
@ -52,7 +50,6 @@ const STATS_POLL_INTERVAL = 30000
type UsePlayersStatsArgs = { type UsePlayersStatsArgs = {
matchProfile: MatchInfo, matchProfile: MatchInfo,
playingProgress: number, playingProgress: number,
selectedPlaylist?: PlaylistOption,
selectedStatsTable: StatsTabs, selectedStatsTable: StatsTabs,
selectedTab: Tabs, selectedTab: Tabs,
setIsPlayersStatsFetching: Dispatch<SetStateAction<boolean>>, setIsPlayersStatsFetching: Dispatch<SetStateAction<boolean>>,
@ -67,7 +64,6 @@ type PlayersData = {
export const usePlayersStats = ({ export const usePlayersStats = ({
matchProfile, matchProfile,
playingProgress, playingProgress,
selectedPlaylist,
selectedStatsTable, selectedStatsTable,
selectedTab, selectedTab,
setIsPlayersStatsFetching, setIsPlayersStatsFetching,
@ -147,8 +143,7 @@ export const usePlayersStats = ({
const isTeam1Selected = selectedStatsTable === StatsTabs.TEAM1 const isTeam1Selected = selectedStatsTable === StatsTabs.TEAM1
if ( if (
selectedPlaylist?.id !== FULL_GAME_KEY selectedTab !== Tabs.STATS
|| selectedTab !== Tabs.STATS
|| !includes([StatsTabs.TEAM1, StatsTabs.TEAM2], selectedStatsTable) || !includes([StatsTabs.TEAM1, StatsTabs.TEAM2], selectedStatsTable)
|| !matchProfile?.team1.id || !matchProfile?.team1.id
|| !matchProfile?.team2.id || !matchProfile?.team2.id
@ -195,7 +190,6 @@ export const usePlayersStats = ({
setIsPlayersStatsFetching(false) setIsPlayersStatsFetching(false)
// eslint-disable-next-line react-hooks/exhaustive-deps // eslint-disable-next-line react-hooks/exhaustive-deps
}, REQUEST_DELAY), [ }, REQUEST_DELAY), [
selectedPlaylist?.id,
fetchPlayers, fetchPlayers,
fetchPlayersStats, fetchPlayersStats,
setPlayersStats, setPlayersStats,

@ -1,10 +1,8 @@
import { useState, useEffect } from 'react' import { useState, useEffect } from 'react'
import map from 'lodash/map' import map from 'lodash/map'
import isEqual from 'lodash/isEqual'
import type { import type {
Episode,
Episodes, Episodes,
Events, Events,
MatchInfo, MatchInfo,
@ -36,18 +34,6 @@ type PlayNextEpisodeArgs = {
order?: number, order?: number,
} }
const EPISODE_TIMESTAMP_OFFSET = 0.001
const addOffset = ({
e,
h,
s,
}: Episode) => ({
e: e + EPISODE_TIMESTAMP_OFFSET,
h,
s: s + EPISODE_TIMESTAMP_OFFSET,
})
export const useStatsTab = ({ export const useStatsTab = ({
disablePlayingEpisodes, disablePlayingEpisodes,
handlePlaylistClick, handlePlaylistClick,
@ -82,15 +68,7 @@ export const useStatsTab = ({
} }
const getEpisodesToPlay = (episodes: Episodes) => map(episodes, (episode, i) => ({ const getEpisodesToPlay = (episodes: Episodes) => map(episodes, (episode, i) => ({
episodes: [ episodes: [episode],
/** При проигрывании нового эпизода с такими же e и s, как у текущего
воспроизведение начинается не с начала, чтобы пофиксить это добавляем
небольшой оффсет
*/
isEqual(episode, selectedPlaylist?.episodes[0])
? addOffset(episode)
: episode,
],
id: i, id: i,
type: PlaylistTypes.EVENT, type: PlaylistTypes.EVENT,
})) as Array<EventPlaylistOption> })) as Array<EventPlaylistOption>

@ -25,9 +25,7 @@ import { usePageParams } from 'hooks'
import { getLocalStorageItem } from 'helpers/getLocalStorage' import { getLocalStorageItem } from 'helpers/getLocalStorage'
import type { PlaylistOption } from 'features/MatchPage/types'
import { StatsType, Tabs as StatsTab } from 'features/MatchSidePlaylists/components/TabStats/config' import { StatsType, Tabs as StatsTab } from 'features/MatchSidePlaylists/components/TabStats/config'
import { FULL_GAME_KEY } from 'features/MatchPage/helpers/buildPlaylists'
import { getHalfTime } from 'features/MatchPage/helpers/getHalfTime' import { getHalfTime } from 'features/MatchPage/helpers/getHalfTime'
import { TOUR_COMPLETED_STORAGE_KEY } from 'features/MatchTour' import { TOUR_COMPLETED_STORAGE_KEY } from 'features/MatchTour'
import { Tabs } from 'features/MatchSidePlaylists/config' import { Tabs } from 'features/MatchSidePlaylists/config'
@ -40,7 +38,6 @@ const STATS_POLL_INTERVAL = 30000
type UseTeamsStatsArgs = { type UseTeamsStatsArgs = {
matchProfile: MatchInfo, matchProfile: MatchInfo,
playingProgress: number, playingProgress: number,
selectedPlaylist?: PlaylistOption,
selectedStatsTable: StatsTab, selectedStatsTable: StatsTab,
selectedTab: Tabs, selectedTab: Tabs,
setIsTeamsStatsFetching: Dispatch<SetStateAction<boolean>>, setIsTeamsStatsFetching: Dispatch<SetStateAction<boolean>>,
@ -54,7 +51,6 @@ type TeamsStats = {
export const useTeamsStats = ({ export const useTeamsStats = ({
matchProfile, matchProfile,
playingProgress, playingProgress,
selectedPlaylist,
selectedStatsTable, selectedStatsTable,
selectedTab, selectedTab,
setIsTeamsStatsFetching, setIsTeamsStatsFetching,
@ -101,7 +97,6 @@ export const useTeamsStats = ({
if ( if (
!sportName !sportName
|| selectedPlaylist?.id !== FULL_GAME_KEY
|| !videoBounds || !videoBounds
|| selectedTab !== Tabs.STATS || selectedTab !== Tabs.STATS
|| selectedStatsTable !== StatsTab.TEAMS || selectedStatsTable !== StatsTab.TEAMS
@ -129,7 +124,6 @@ export const useTeamsStats = ({
matchProfile?.video_bounds, matchProfile?.video_bounds,
matchProfile?.live, matchProfile?.live,
matchScore?.video_bounds, matchScore?.video_bounds,
selectedPlaylist?.id,
matchId, matchId,
setIsTeamsStatsFetching, setIsTeamsStatsFetching,
sportName, sportName,

@ -1,11 +1,16 @@
import { Fragment, useRef } from 'react' import { Fragment, useRef } from 'react'
import { createPortal } from 'react-dom'
import { useQueryClient } from 'react-query' import { useQueryClient } from 'react-query'
import { useTour } from '@reactour/tour' import { useTour } from '@reactour/tour'
import isNumber from 'lodash/isNumber' import isNumber from 'lodash/isNumber'
import { KEYBOARD_KEYS, querieKeys } from 'config' import {
isMobileDevice,
KEYBOARD_KEYS,
querieKeys,
} from 'config'
import type { import type {
Param, Param,
@ -14,7 +19,12 @@ import type {
} from 'requests' } from 'requests'
import { getStatsEvents } from 'requests' import { getStatsEvents } from 'requests'
import { usePageParams, useEventListener } from 'hooks' import {
usePageParams,
useEventListener,
useTooltip,
useModalRoot,
} from 'hooks'
import { getHalfTime } from 'features/MatchPage/helpers/getHalfTime' import { getHalfTime } from 'features/MatchPage/helpers/getHalfTime'
import { useMatchPageStore } from 'features/MatchPage/store' import { useMatchPageStore } from 'features/MatchPage/store'
@ -24,6 +34,7 @@ import { Spotlight, Steps } from 'features/MatchTour'
import { StatsType } from '../TabStats/config' import { StatsType } from '../TabStats/config'
import { CircleAnimationBar } from '../CircleAnimationBar' import { CircleAnimationBar } from '../CircleAnimationBar'
import { Tooltip } from '../TabStats/styled'
import { import {
CellContainer, CellContainer,
ParamValueContainer, ParamValueContainer,
@ -59,14 +70,28 @@ export const Cell = ({
watchAllEpisodesTimer, watchAllEpisodesTimer,
} = useMatchPageStore() } = useMatchPageStore()
const { shortSuffix, suffix } = useLexicsStore() const { suffix } = useLexicsStore()
const { currentStep, isOpen } = useTour() const { currentStep, isOpen } = useTour()
const client = useQueryClient() const client = useQueryClient()
const {
isTooltipShown,
onMouseLeave,
onMouseOver,
tooltipStyle,
tooltipText,
} = useTooltip()
const modalRoot = useModalRoot()
const { translate } = useLexicsStore()
const matchScore = client.getQueryData<MatchScore>(querieKeys.matchScore) const matchScore = client.getQueryData<MatchScore>(querieKeys.matchScore)
const isTeam1 = teamId === profile?.team1.id
const getDisplayedValue = (val: number | null) => ( const getDisplayedValue = (val: number | null) => (
isNumber(val) ? String(val) : '-' isNumber(val) ? String(val) : '-'
) )
@ -104,7 +129,7 @@ export const Cell = ({
setEpisodeInfo({ setEpisodeInfo({
episodesCount: param.val!, episodesCount: param.val!,
paramName, paramName,
playerOrTeamName: teamId === profile?.team1.id playerOrTeamName: isTeam1
? profile.team1[`name_${suffix}`] ? profile.team1[`name_${suffix}`]
: profile?.team2[`name_${suffix}`] || '', : profile?.team2[`name_${suffix}`] || '',
}) })
@ -122,7 +147,7 @@ export const Cell = ({
? teamStatItem.param1 ? teamStatItem.param1
: teamStatItem.param2) : teamStatItem.param2)
param && onParamClick(param, teamStatItem[`name_${shortSuffix}`]) param && onParamClick(param, translate(teamStatItem.lexic))
}, },
event: 'keydown', event: 'keydown',
target: paramValueContainerRef, target: paramValueContainerRef,
@ -137,7 +162,7 @@ export const Cell = ({
&& playingData.team.paramId === teamStatItem.param1.id && playingData.team.paramId === teamStatItem.param1.id
&& playingData.team.id === teamId && playingData.team.id === teamId
? ( ? (
<ParamValue> <ParamValue onMouseLeave={onMouseLeave}>
<CircleAnimationBar <CircleAnimationBar
text={getDisplayedValue(teamStatItem.param1.val)} text={getDisplayedValue(teamStatItem.param1.val)}
size={22} size={22}
@ -147,13 +172,21 @@ export const Cell = ({
: ( : (
<ParamValue <ParamValue
clickable={isClickable(teamStatItem.param1)} clickable={isClickable(teamStatItem.param1)}
onClick={() => onParamClick(teamStatItem.param1, teamStatItem[`name_${shortSuffix}`])} onClick={() => onParamClick(teamStatItem.param1, translate(teamStatItem.lexic))}
data-param-id={teamStatItem.param1.id} data-param-id={teamStatItem.param1.id}
hasValue={Boolean(teamStatItem.param1.val)} hasValue={Boolean(teamStatItem.param1.val)}
// eslint-disable-next-line react/jsx-props-no-spreading // eslint-disable-next-line react/jsx-props-no-spreading
{...firstClickableParam === teamStatItem.param1 && { {...firstClickableParam === teamStatItem.param1 && {
'data-step': Steps.ClickToWatchPlaylist, 'data-step': Steps.ClickToWatchPlaylist,
}} }}
// eslint-disable-next-line react/jsx-props-no-spreading
{...!isMobileDevice && isNumber(teamStatItem.param1.val) && teamStatItem.param2 && {
onMouseLeave,
onMouseOver: onMouseOver({
horizontalPosition: isTeam1 ? 'left' : 'right',
tooltipText: translate(teamStatItem.param1.lexic),
}),
}}
> >
{getDisplayedValue(teamStatItem.param1.val)} {getDisplayedValue(teamStatItem.param1.val)}
{firstClickableParam === teamStatItem.param1 {firstClickableParam === teamStatItem.param1
@ -168,7 +201,7 @@ export const Cell = ({
&& playingData.team.paramId === teamStatItem.param2.id && playingData.team.paramId === teamStatItem.param2.id
&& playingData.team.id === teamId && playingData.team.id === teamId
? ( ? (
<ParamValue> <ParamValue onMouseLeave={onMouseLeave}>
<CircleAnimationBar <CircleAnimationBar
text={getDisplayedValue(teamStatItem.param2.val)} text={getDisplayedValue(teamStatItem.param2.val)}
size={22} size={22}
@ -180,13 +213,24 @@ export const Cell = ({
<Divider>/</Divider> <Divider>/</Divider>
<ParamValue <ParamValue
clickable={isClickable(teamStatItem.param2)} clickable={isClickable(teamStatItem.param2)}
onClick={() => onParamClick(teamStatItem.param2!, teamStatItem[`name_${shortSuffix}`])} onClick={() => onParamClick(
teamStatItem.param2!,
translate(teamStatItem.lexic),
)}
data-param-id={teamStatItem.param2.id} data-param-id={teamStatItem.param2.id}
hasValue={Boolean(teamStatItem.param2.val)} hasValue={Boolean(teamStatItem.param2.val)}
// eslint-disable-next-line react/jsx-props-no-spreading // eslint-disable-next-line react/jsx-props-no-spreading
{...firstClickableParam === teamStatItem.param2 && { {...firstClickableParam === teamStatItem.param2 && {
'data-step': Steps.ClickToWatchPlaylist, 'data-step': Steps.ClickToWatchPlaylist,
}} }}
// eslint-disable-next-line react/jsx-props-no-spreading
{...!isMobileDevice && isNumber(teamStatItem.param2.val) && {
onMouseLeave,
onMouseOver: onMouseOver({
horizontalPosition: isTeam1 ? 'left' : 'right',
tooltipText: translate(teamStatItem.param2.lexic),
}),
}}
> >
{getDisplayedValue(teamStatItem.param2.val)} {getDisplayedValue(teamStatItem.param2.val)}
{firstClickableParam === teamStatItem.param2 {firstClickableParam === teamStatItem.param2
@ -198,6 +242,12 @@ export const Cell = ({
</Fragment> </Fragment>
)} )}
</ParamValueContainer> </ParamValueContainer>
{isTooltipShown && modalRoot.current && createPortal(
<Tooltip style={tooltipStyle}>
{tooltipText}
</Tooltip>,
modalRoot.current,
)}
</CellContainer> </CellContainer>
) )
} }

@ -1,8 +1,12 @@
import { useEffect } from 'react' import { useEffect, useMemo } from 'react'
import find from 'lodash/find' import find from 'lodash/find'
import reduce from 'lodash/reduce'
import type { TeamStatItem } from 'requests'
import { useMatchPageStore } from 'features/MatchPage/store' import { useMatchPageStore } from 'features/MatchPage/store'
import { useLexicsConfig } from 'features/LexicsStore'
export const useTeamsStatsTable = () => { export const useTeamsStatsTable = () => {
const { const {
@ -13,6 +17,26 @@ export const useTeamsStatsTable = () => {
teamsStats, teamsStats,
} = useMatchPageStore() } = useMatchPageStore()
const lexicsIds = useMemo(
() => (
profile
? reduce<TeamStatItem, Array<number>>(
teamsStats[profile.team1.id],
(acc, curr) => {
!acc.includes(curr.lexic) && acc.push(curr.lexic)
!acc.includes(curr.param1.lexic) && acc.push(curr.param1.lexic)
curr.param2 && !acc.includes(curr.param2.lexic) && acc.push(curr.param2.lexic)
return acc
},
[],
)
: []),
[profile, teamsStats],
)
useLexicsConfig(lexicsIds)
const getStatItemById = (paramId: number) => { const getStatItemById = (paramId: number) => {
if (!profile) return null if (!profile) return null

@ -3,7 +3,6 @@ import { useTour } from '@reactour/tour'
import map from 'lodash/map' import map from 'lodash/map'
import { useMatchPageStore } from 'features/MatchPage/store' import { useMatchPageStore } from 'features/MatchPage/store'
import { useLexicsStore } from 'features/LexicsStore'
import { Loader } from 'features/Loader' import { Loader } from 'features/Loader'
import { defaultTheme } from 'features/Theme/config' import { defaultTheme } from 'features/Theme/config'
@ -32,8 +31,6 @@ export const TeamsStatsTable = () => {
getStatItemById, getStatItemById,
} = useTeamsStatsTable() } = useTeamsStatsTable()
const { shortSuffix } = useLexicsStore()
const { isOpen } = useTour() const { isOpen } = useTour()
if (!profile) return null if (!profile) return null
@ -69,7 +66,6 @@ export const TeamsStatsTable = () => {
<tbody> <tbody>
{map(teamsStats[profile.team1.id], (team1StatItem) => { {map(teamsStats[profile.team1.id], (team1StatItem) => {
const team2StatItem = getStatItemById(team1StatItem.param1.id) const team2StatItem = getStatItemById(team1StatItem.param1.id)
const statItemTitle = team1StatItem[`name_${shortSuffix}`]
return ( return (
<Row key={team1StatItem.param1.id}> <Row key={team1StatItem.param1.id}>
@ -80,7 +76,7 @@ export const TeamsStatsTable = () => {
/> />
<CellContainer> <CellContainer>
<StatItemTitle>{statItemTitle}</StatItemTitle> <StatItemTitle t={team1StatItem.lexic} />
</CellContainer> </CellContainer>
<Cell <Cell

@ -4,6 +4,7 @@ import { isMobileDevice } from 'config'
import { Name } from 'features/Name' import { Name } from 'features/Name'
import { customScrollbar } from 'features/Common' import { customScrollbar } from 'features/Common'
import { T9n } from 'features/T9n'
export const Container = styled.div`` export const Container = styled.div``
@ -59,11 +60,12 @@ export const CellContainer = styled.td`
} }
:first-child, :last-child { :first-child, :last-child {
width: 32px; width: 50px;
} }
:first-child { :first-child {
padding-left: 12px; padding-left: 12px;
text-align: left;
} }
:last-child { :last-child {
@ -122,7 +124,7 @@ export const ParamValue = styled.span.attrs(({ clickable }: TParamValue) => ({
: '')} : '')}
` `
export const StatItemTitle = styled.span` export const StatItemTitle = styled(T9n)`
color: ${({ theme }) => theme.colors.white}; color: ${({ theme }) => theme.colors.white};
letter-spacing: -0.078px; letter-spacing: -0.078px;
text-transform: uppercase; text-transform: uppercase;

@ -339,7 +339,7 @@ export const useVideoPlayer = ({
setPlayerState({ playedProgress: value }) setPlayerState({ playedProgress: value })
timeForStatistics.current = (value + chapter.startMs) / 1000 timeForStatistics.current = (value + chapter.startMs) / 1000
setPlayingProgress(Math.floor(value / 1000)) chapter.isFullMatchChapter && setPlayingProgress(Math.floor(value / 1000))
progressChangeCallback(value / 1000) progressChangeCallback(value / 1000)
} }
@ -530,6 +530,20 @@ export const useVideoPlayer = ({
selectedPlaylist, selectedPlaylist,
]) ])
/**
* Для воcпроизведения нового эпизода, аналогичного текущему, с начала
*/
useEffect(() => {
if (chaptersProps[0].isFullMatchChapter) return
setPlayerState({
...initialState,
chapters: chaptersProps,
playing: true,
seek: chaptersProps[0].startOffsetMs / 1000,
})
}, [chaptersProps, setPlayerState])
useEffect(() => { useEffect(() => {
if (( if ((
chapters[0]?.isFullMatchChapter) chapters[0]?.isFullMatchChapter)

@ -1,9 +1,6 @@
import { useMemo } from 'react'
import { client } from 'config/clients' import { client } from 'config/clients'
import { formIds } from 'config/form' import { formIds } from 'config/form'
import { AUTH_SERVICE } from 'config/routes' import { AUTH_SERVICE } from 'config/routes'
import { ClientNames } from 'config/clients/types'
import { Combobox } from 'features/Combobox' import { Combobox } from 'features/Combobox'
import { Input } from 'features/Common' import { Input } from 'features/Common'
@ -47,15 +44,6 @@ export const PersonalInfoForm = (props: Props) => {
updateFormValue, updateFormValue,
} = useUserInfo(props) } = useUserInfo(props)
const isPrivacyPolicyShown = useMemo(() => {
switch (client.name) {
case ClientNames.Facr:
return false
default:
return true
}
}, [])
return ( return (
<Form> <Form>
<Input <Input
@ -136,15 +124,13 @@ export const PersonalInfoForm = (props: Props) => {
> >
<T9n t='terms_and_conditions' /> <T9n t='terms_and_conditions' />
</PrivacyPolicyLink> </PrivacyPolicyLink>
{isPrivacyPolicyShown && ( <PrivacyPolicyLink
<PrivacyPolicyLink target='_blank'
target='_blank' href={`${AUTH_SERVICE}${client.privacyLink}`}
href={`${AUTH_SERVICE}${client.privacyLink}`} id='personal_policy'
id='personal_policy' >
> <T9n t='privacy_policy_and_statement' />
<T9n t='privacy_policy_and_statement' /> </PrivacyPolicyLink>
</PrivacyPolicyLink>
)}
</PrivacyWrapper> </PrivacyWrapper>
</Form> </Form>
) )

@ -1,13 +1,5 @@
import * as Sentry from '@sentry/react'
export const logoutIfUnauthorized = async (response: Response) => { export const logoutIfUnauthorized = async (response: Response) => {
/* отключили из-за доступа без авторизации */ /* отключили из-за доступа без авторизации */
const body = await response.json()
if (response.status === 400) {
Sentry.captureException(body)
}
if (response.status === 401 || response.status === 403) { if (response.status === 401 || response.status === 403) {
window.dispatchEvent(new Event('FORBIDDEN_REQUEST')) window.dispatchEvent(new Event('FORBIDDEN_REQUEST'))
} }
@ -16,5 +8,6 @@ export const logoutIfUnauthorized = async (response: Response) => {
// eslint-disable-next-line no-console // eslint-disable-next-line no-console
console.error(error) console.error(error)
const body = await response.json()
return Promise.reject(body) return Promise.reject(body)
} }

@ -5,24 +5,11 @@ import {
} from 'react' } from 'react'
import ReactDOM from 'react-dom' import ReactDOM from 'react-dom'
import * as Sentry from '@sentry/react' import { isIOS } from 'config/userAgent'
import { BrowserTracing } from '@sentry/react'
import { isIOS, ENV } from 'config'
// import { makeServer } from 'utilits/mirage/Mirage' // import { makeServer } from 'utilits/mirage/Mirage'
import * as serviceWorker from './serviceWorker' import * as serviceWorker from './serviceWorker'
if (process.env.NODE_ENV !== 'development') {
Sentry.init({
dsn: 'https://bbe0cdfb954644ebaf3be16bb472cc3d@sentry.insports.tv/21',
environment: ENV,
integrations: [new BrowserTracing()],
tracesSampleRate: 1.0,
})
}
export const App = process.env.REACT_APP_TYPE === 'auth-service' export const App = process.env.REACT_APP_TYPE === 'auth-service'
? lazy(() => import('features/AuthServiceApp')) ? lazy(() => import('features/AuthServiceApp'))
: lazy(() => import('features/App')) : lazy(() => import('features/App'))

Loading…
Cancel
Save