Skip to content

Commit

Permalink
feat(frontend): default scale to the latest 7 days for long game
Browse files Browse the repository at this point in the history
  • Loading branch information
GZTimeWalker committed Aug 7, 2023
1 parent e926946 commit 989ac31
Show file tree
Hide file tree
Showing 8 changed files with 39 additions and 41 deletions.
13 changes: 3 additions & 10 deletions src/GZCTF/ClientApp/src/components/GameCard.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import dayjs, { Dayjs } from 'dayjs'
import { FC } from 'react'
import { Link } from 'react-router-dom'
import {
Expand All @@ -15,6 +14,7 @@ import {
} from '@mantine/core'
import { mdiChevronTripleRight, mdiFlagOutline } from '@mdi/js'
import { Icon } from '@mdi/react'
import { getGameStatus } from '@Utils/useGame'
import { BasicGameInfoModel } from '@Api'

export enum GameStatus {
Expand All @@ -33,21 +33,14 @@ interface GameCardProps {
game: BasicGameInfoModel
}

export const getGameStatus = (start: Dayjs, end: Dayjs) => {
const now = dayjs()
return end < now ? GameStatus.Ended : start > now ? GameStatus.Coming : GameStatus.OnGoing
}

const GameCard: FC<GameCardProps> = ({ game, ...others }) => {
const theme = useMantineTheme()

const { summary, title, poster, start, end, limit } = game
const startTime = dayjs(start)
const endTime = dayjs(end)
const { summary, title, poster, limit } = game
const { startTime, endTime, status } = getGameStatus(game)

const duration = endTime.diff(startTime, 'hours')

const status = getGameStatus(startTime, endTime)
const color = GameColorMap.get(status)

return (
Expand Down
10 changes: 4 additions & 6 deletions src/GZCTF/ClientApp/src/components/RecentGame.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ import {
} from '@mantine/core'
import { mdiFlagOutline } from '@mdi/js'
import { Icon } from '@mdi/react'
import { getGameStatus, GameColorMap, GameStatus } from '@Components/GameCard'
import { GameColorMap, GameStatus } from '@Components/GameCard'
import { getGameStatus } from '@Utils/useGame'
import { BasicGameInfoModel } from '@Api'

export interface RecentGameProps {
Expand All @@ -26,12 +27,9 @@ const POSTER_HEIGHT = '15vh'
const RecentGame: FC<RecentGameProps> = ({ game, ...others }) => {
const theme = useMantineTheme()

const { title, poster, start, end } = game
const { title, poster } = game
const { startTime, endTime, status } = getGameStatus(game)

const startTime = dayjs(start)
const endTime = dayjs(end)

const status = getGameStatus(startTime, endTime)
const color = GameColorMap.get(status)

const duration =
Expand Down
9 changes: 4 additions & 5 deletions src/GZCTF/ClientApp/src/components/RecentGameSlide.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ import dayjs from 'dayjs'
import { FC } from 'react'
import { Link } from 'react-router-dom'
import { Badge, Group, Stack, Title, createStyles, Paper } from '@mantine/core'
import { getGameStatus, GameColorMap, GameStatus } from '@Components/GameCard'
import { GameColorMap, GameStatus } from '@Components/GameCard'
import { RecentGameProps } from '@Components/RecentGame'
import { getGameStatus } from '@Utils/useGame'

const useStyles = createStyles((theme) => ({
card: {
Expand All @@ -29,12 +30,10 @@ const useStyles = createStyles((theme) => ({
const RecentGameSlide: FC<RecentGameProps> = ({ game, ...others }) => {
const { classes } = useStyles()

const { title, poster, start, end } = game
const { title, poster } = game

const startTime = dayjs(start)
const endTime = dayjs(end)
const { startTime, endTime, status } = getGameStatus(game)

const status = getGameStatus(startTime, endTime)
const color = GameColorMap.get(status)

const duration =
Expand Down
20 changes: 14 additions & 6 deletions src/GZCTF/ClientApp/src/components/TimeLine.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import ReactEcharts from 'echarts-for-react'
import { FC, useEffect, useState } from 'react'
import { useParams } from 'react-router-dom'
import { useMantineTheme } from '@mantine/core'
import { useGame, useGameScoreboard } from '@Utils/useGame'
import { getGameStatus, useGame, useGameScoreboard } from '@Utils/useGame'

interface TimeLineProps {
organization: string | null
Expand All @@ -18,14 +18,22 @@ const TimeLine: FC<TimeLineProps> = ({ organization }) => {

const { game } = useGame(numId)

const { startTime, endTime, progress } = getGameStatus(game)

const totDuration = endTime.diff(startTime, 'd')
const longGame = totDuration > 14
const weekProgress = (7 / totDuration) * 100

const scaleStart = progress - weekProgress
const scaleEnd = progress

const [now, setNow] = useState<Date>(new Date())
const [chartData, setChartData] = useState<any>()

useEffect(() => {
if (!scoreboard?.timeLines || !game) return

const timeLine = scoreboard?.timeLines[organization ?? 'all'] ?? []
const endTime = dayjs(game.end)
const current = dayjs()
const last = endTime.diff(current, 's') < 0 ? endTime : current

Expand Down Expand Up @@ -138,14 +146,14 @@ const TimeLine: FC<TimeLineProps> = ({ organization }) => {
dataZoom: [
{
type: 'inside',
start: 0,
end: 100,
start: longGame ? scaleStart : 0,
end: longGame ? scaleEnd : 100,
xAxisIndex: 0,
filterMode: 'none',
},
{
start: 0,
end: 100,
start: longGame ? scaleStart : 0,
end: longGame ? scaleEnd : 100,
xAxisIndex: 0,
showDetail: false,
},
Expand Down
10 changes: 3 additions & 7 deletions src/GZCTF/ClientApp/src/components/WithGameTab.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { Icon } from '@mdi/react'
import CustomProgress from '@Components/CustomProgress'
import IconTabs from '@Components/IconTabs'
import { RequireRole } from '@Components/WithRole'
import { useGame } from '@Utils/useGame'
import { getGameStatus, useGame } from '@Utils/useGame'
import { usePageTitle } from '@Utils/usePageTitle'
import { useUserRole } from '@Utils/useUser'
import { DetailedGameInfoModel, ParticipationStatus, Role } from '@Api'
Expand Down Expand Up @@ -47,21 +47,17 @@ const pages = [
dayjs.extend(duration)

const GameCountdown: FC<{ game?: DetailedGameInfoModel }> = ({ game }) => {
const start = dayjs(game?.start ?? new Date())
const end = dayjs(game?.end ?? new Date())
const total = end.diff(start)
const { endTime, progress } = getGameStatus(game)

const [now, setNow] = useState(dayjs())
const current = now.diff(start)

useEffect(() => {
if (!game || dayjs() > dayjs(game.end)) return
const interval = setInterval(() => setNow(dayjs()), 1000)
return () => clearInterval(interval)
}, [game])

const progress = (current / total) * 100
const countdown = dayjs.duration(end.diff(now))
const countdown = dayjs.duration(endTime.diff(now))

return (
<Card
Expand Down
7 changes: 3 additions & 4 deletions src/GZCTF/ClientApp/src/pages/admin/games/Index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,13 @@ import {
mdiPlus,
} from '@mdi/js'
import { Icon } from '@mdi/react'
import { GameColorMap, getGameStatus } from '@Components/GameCard'
import { GameColorMap } from '@Components/GameCard'
import AdminPage from '@Components/admin/AdminPage'
import GameCreateModal from '@Components/admin/GameCreateModal'
import { showErrorNotification } from '@Utils/ApiErrorHandler'
import { useTableStyles } from '@Utils/ThemeOverride'
import { useArrayResponse } from '@Utils/useArrayResponse'
import { getGameStatus } from '@Utils/useGame'
import api, { GameInfoModel } from '@Api'

const ITEM_COUNT_PER_PAGE = 30
Expand Down Expand Up @@ -119,9 +120,7 @@ const Games: FC = () => {
<tbody>
{games &&
games.map((game) => {
const startTime = dayjs(game.start)
const endTime = dayjs(game.end)
const status = getGameStatus(startTime, endTime)
const { startTime, endTime, status } = getGameStatus(game)
const color = GameColorMap.get(status)

return (
Expand Down
2 changes: 1 addition & 1 deletion src/GZCTF/ClientApp/src/pages/games/[id]/Index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,7 @@ const GameDetail: FC = () => {
</Text>
</Stack>
</Group>
<CustomProgress percentage={progress * 100} />
<CustomProgress percentage={progress} />
<Group>{ControlButtons}</Group>
</Stack>
<BackgroundImage className={classes.banner} src={game?.poster ?? ''} radius="sm">
Expand Down
9 changes: 7 additions & 2 deletions src/GZCTF/ClientApp/src/utils/useGame.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import dayjs from 'dayjs'
import { GameStatus } from '@Components/GameCard'
import { OnceSWRConfig } from '@Utils/useConfig'
import api, { DetailedGameInfoModel, ParticipationStatus } from '@Api'

Expand All @@ -11,14 +12,18 @@ export const getGameStatus = (game?: DetailedGameInfoModel) => {

const finished = current > duriation
const started = current > 0
const progress = started ? (finished ? 100 : current / duriation) : 0
const total = endTime.diff(startTime, 'minute')
const progress = started ? (finished ? 1 : current / duriation) : 0
const status = started ? (finished ? GameStatus.Ended : GameStatus.OnGoing) : GameStatus.Coming

return {
startTime,
endTime,
finished,
started,
progress,
progress: progress * 100,
total,
status,
}
}

Expand Down

0 comments on commit 989ac31

Please sign in to comment.